英文:
How to pass the right link to a button in a list from Firebase with SwiftUI
问题
I am making an app that has a series of articles on the web. It generates a list from a Firebase database that has the Title, URL, etc in it. Then the user taps on the title, and a webview pulls up with the site in it.
The problem right now is that the list populates with all the right data and is ordered the way I want it, but no matter which title I tap on, it shows the same site in the webview. It's just one of the links from the database. For example, an article on Y is one of the articles in the database. If I tap on any title in the list, it pulls up the link for article Y.
Here is how I fetch the data:
struct Algorithm: Identifiable {
var id: String
var title: String
var link: String
var keywords: String
var category: String
}
class ArticlesViewModel: ObservableObject {
@Published var books = [Algorithm]()
private var db = Firestore.firestore()
func fetchData() {
db.collection("MainLibrary").order(by: "Title", descending: false).getDocuments { (querySnapshot, error) in
guard let documents = querySnapshot?.documents else {
print("No documents")
return
}
self.books = documents.map { queryDocumentSnapshot -> Algorithm in
let data = queryDocumentSnapshot.data()
let id = data["ref"] as? String ?? ""
let title = data["Title"] as? String ?? ""
let link = data["url"] as? String ?? ""
let category = data["Category"] as? String ?? ""
let keywords = data["Keywords"] as? String ?? ""
return Algorithm(id: id, title: title, link: link, keywords: keywords, category: category)
}
print(self.books)
}
}
}
Here is the code for displaying the list:
List(viewModel.books) { algorithm in
VStack(alignment: .leading) {
HStack {
Button(algorithm.title){
showWebViewArts.toggle()
}
.listRowSeparator(.visible, edges: .all)
.listRowSeparatorTint(Color.red)
.font(.headline)
.foregroundColor(.indigo)
}
.sheet(isPresented: $showWebViewArts) {
VStack(spacing: 0) {
HeaderView()
WebView(url: URL(string: algorithm.link)!)
.background(Color.accentColor)
}
}
}
}
There is also a private var for showWebViewAlerts
.
I tested that it's pulling the right URL for each article (hence the text item with the link in it), and it does. But then when I tap, it just pulls up the same incorrect link.
英文:
I am making an app that has a series of articles on the web. It generates a list from a Firebase database that has the Title, URL, etc in it. Then the user taps on the title, and a webview pulls up with the site in it.
The problem right now is that the list populates with all the right data and is ordered the way I want it, but no matter which title I tap on, it shows the same site in the webview. It's just one of the links from the database. For example, an article on Y is one of the articles in the database. If I tap on any title in the list, it pulls up the link for article Y.
Here is how I fetch the data:
struct Algorithm: Identifiable {
var id: String
var title: String
var link: String
var keywords: String
var category: String
}
class ArticlesViewModel: ObservableObject {
@Published var books = [Algorithm]()
private var db = Firestore.firestore()
func fetchData() {
db.collection("MainLibrary").order(by: "Title", descending: false).getDocuments { (querySnapshot, error) in
guard let documents = querySnapshot?.documents else {
print("No documents")
return
}
self.books = documents.map { queryDocumentSnapshot -> Algorithm in
let data = queryDocumentSnapshot.data()
let id = data["ref"] as? String ?? ""
let title = data["Title"] as? String ?? ""
let link = data["url"] as? String ?? ""
let category = data["Category"] as? String ?? ""
let keywords = data["Keywords"] as? String ?? ""
return Algorithm(id: id, title: title, link: link, keywords: keywords, category: category)
}
print(self.books)
}
}
}
Here is the code for displaying the list:
List(viewModel.books) { algorithm in // (2)
VStack(alignment: .leading) {
HStack {
Button(algorithm.title){
showWebViewArts.toggle()
}
.listRowSeparator(.visible, edges: .all)
.listRowSeparatorTint(Color.red)
.font(.headline)
.foregroundColor(.indigo)
// Text(algorithm.link )
// .font(.subheadline)
}
.sheet(isPresented: $showWebViewArts) {
VStack(spacing: 0) {
HeaderView()
WebView(url: URL(string: algorithm.link)!)
//.padding(.top, 50)
.background(Color.accentColor)
}
}
}
}
There is also a private var for showWebViewAlerts.
I tested that it's pulling the right url for each article (hence the text item with the link in it), and it does. But then when I tap, it just pulls up the same incorrect link.
答案1
得分: 0
请尝试这种方法,使用.sheet(item:...)
而不是.sheet(isPresented: ...)
,并将其添加到List
中,如示例代码所示:
@State var selection: Algorithm? // <-- 这里
List(viewModel.books) { algorithm in
...
Button(algorithm.title){
selection = algorithm // <-- 这里
}
...
}
.sheet(item: $selection) { algorithm in // <-- 这里在List之外
VStack(spacing: 0) {
HeaderView()
WebView(url: URL(string: algorithm.link)!)
//.padding(.top, 50)
.background(Color.accentColor)
}
}
英文:
Try this approach, using .sheet(item:...)
instead of .sheet(isPresented: ...)
and adding it to the List
, as shown in the example code:
@State var selection: Algorithm? // <-- here
List(viewModel.books) { algorithm in
...
Button(algorithm.title){
selection = algorithm // <-- here
}
...
}
.sheet(item: $selection) { algorithm in // <-- here outside the List
VStack(spacing: 0) {
HeaderView()
WebView(url: URL(string: algorithm.link)!)
//.padding(.top, 50)
.background(Color.accentColor)
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论