Swift UI @State 确实在第一次点击时设置

问题描述

我有一个简单的自定义视图列表。需要发生的是选择其中一个项目时,它需要显示该项目的详细视图。在我的代码中,当我第一次选择一个项目时,@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
    
}

}

解决方法

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

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

就您的具体情况而言,很难说清楚,因为我没有您的 UserProfile 代码,但我建议您:

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

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

请看this

当我在您的 State 代码中删除 optional 时,它会起作用。所以请参考这个。

(为了在我这边进行测试,我做了一些改动。)

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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...