【问题标题】:Swift UI @State does get set on the first tapSwiftui @State 确实在第一次点击时设置
【发布时间】:2021-02-20 01:06:50
【问题描述】:

我有一个自定义视图的简单列表。需要发生什么是选择其中一个项目时,它需要显示该项的详细视图。在我的代码中,当我第一次选择一个项目时,@Statet selectedListener 没有设置,因此详细视图不会出现。如果我继续选择先前选择的相同项目,则行为保持不变。但是,如果我选择不同的项目,它会正常工作,我可以返回到前一个项目并查看其详细视图而不会出现问题。这是一件我想做的简单的事情,只是无法弄清楚我可能做错了什么。任何帮助,将不胜感激。谢谢。

struct ListenersListView<Model>: View where Model: ActiveListenerViewModel {

@ObservedObject var viewModel: Model
@State var showDetail = false
@State var selectedListener: UserProfile? = nil

var body: some View {
    ScrollView {
        VStack(spacing:20) {
            ForEach(viewModel.allActiveListeners) { listener in
                UserImageSection(listener: listener,
                                 subtext: listener.supportAreas)
                    .onTapGesture(perform: {
                        handleTap(listener)
                    })
            }
        }
        
    }
    .padding(.horizontal,20)
    .sheet(isPresented: $showDetail, content: {
        if let listener = selectedListener {
            ListenerDetailView(listener: listener)
        }
        else {
            // It should never come here but when the first item is selected it does. The only way to not come here is to select another item after the first item has been selected.
            Text("Listener not loaded yet")
        }
    })
    
    
}

private func handleTap(_ listener: UserProfile) {
    print("Showing listener \(listener.id)")
    self.selectedListener = listener
    showDetail = true
    
}

}

【问题讨论】:

    标签: swiftui swiftui-state swiftui-ontapgesture


    【解决方案1】:

    在 iOS 14 中,为了让 .sheet 显示最新数据,您必须使用 sheet(item:) 而不是 .sheet(isPresented:)

    你可以在这里看到我的另一个答案:https://stackoverflow.com/a/66190152/560942SwiftUI: Switch .sheet on enum, does not work

    在您的具体情况下,由于我没有您的UserProfile 代码,所以很难说,但我建议您:

    1. 摆脱你的showDetail状态变量
    2. 确保UserProfile 符合Identifiable
    3. 将您的 sheet(isPresented:) 更改为:
    .sheet(item: $selectedListener) { listener in 
      ListenerDetailView(listener: listener)
    } 
    

    【讨论】:

      【解决方案2】:

      这似乎是 iOS 14 中的一个错误。*

      请看this

      当我删除您的 State 代码上的可选项时,它会起作用。所以请参考这个。

      (我改变了一点来测试。)

      @State var showDetail = false
      @State var selectedListener: String = ""
      
      var body: some View {
          ScrollView {
              VStack {
                  Text("Click")
              }
              .contentShape(Rectangle())
              .onTapGesture {
                  handleTap("Handle!")
              }
          }
          .padding(.horizontal,20)
          .sheet(isPresented: $showDetail, content: {
              if let listener = selectedListener {
                  Text("Get called")
              }
              else {
                  // It should never come here but when the first item is selected it does. The only way to not come here is to select another item after the first item has been selected.
                  Text("Listener not loaded yet")
              }
          })
      }
      
      private func handleTap(_ listener: String) {
          print("Showing listener \(listener)")
          self.selectedListener = listener
          print(self.selectedListener)
          showDetail = true
      }
      

      【讨论】:

      • 感谢您的回答 Hwangho 但即使将自定义侦听器对象更改为非可选对象,它也不起作用。 jnpdx 建议的答案非常适合上述问题。
      猜你喜欢
      • 2014-11-09
      • 1970-01-01
      • 2017-07-03
      • 2011-06-08
      • 2014-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多