如何在SwiftUI中从Firebase传递正确的链接给列表中的按钮

huangapple go评论57阅读模式
英文:

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)
     }
  }

huangapple
  • 本文由 发表于 2023年5月7日 00:19:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/76189934.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定