我在SwiftUI的Form
中有一个Picker
,我正在尝试在Picker更改时处理值。我希望通过表示当前选定值的变量上的didSet
实现此目的。
import SwiftUI
struct ContentView: View {
enum TransmissionType: Int {
case automatic
case manual
}
@State private var selectedTransmissionType: Int = TransmissionType.automatic.rawValue {
didSet {
print("selection changed to \(selectedTransmissionType)")
}
}
private let transmissionTypes: [String] = ["Automatic", "Manual"]
var body: some View {
NavigationView {
Form {
Section {
Picker(selection: $selectedTransmissionType,
label: Text("Transmission Type")) {
ForEach(0 ..< transmissionTypes.count) {
Text(self.transmissionTypes[$0])
}
}
}
}
}
}
}
Picker
UI基本按照预期工作:我可以看到默认的值被选中,点击选择器,它打开一个新视图,我可以选择其他值,然后返回到主表单并显示已选择的新值。然而,didSet
从未被调用。我看到了这个问题,但我觉得在我的
View
代码中添加更多内容似乎有点奇怪,而不是在变量更改时仅处理新值,如果这是可能的话。即使它导致了一个更复杂的视图,使用onReceive
是否更好?我的主要问题是:我的代码有什么问题防止didSet
被调用?
我使用了这个示例来达到这个程度。除了我的常规问题外,我还有一些关于这个示例的其他问题: A) 我有一个
enum
和一个Array
来表示相同的两个值,这似乎很奇怪。有人能建议一个更好的结构来避免这种冗余吗?我考虑过一个TransmissionType
对象,但与enum
相比,这似乎过于复杂了...也许不是吗?
B) 点击选择器时,屏幕上的选择器选项会滑动,然后这两个选项会跳起来。这感觉很突兀和跳跃,用户体验很差。这里有什么做错了导致糟糕的UX吗?还是这可能是一个SwiftUI的错误?每次更改选择器时,我都会收到以下错误:
[TableView] Warning once only: UITableView was told to layout its visible cells and other contents without being in the view hierarchy (the table view or one of its superviews has not been added to a window). This may cause bugs by forcing views inside the table view to load and perform layout without accurate information (e.g. table view bounds, trait collection, layout margins, safe area insets, etc), and will also cause unnecessary performance overhead due to extra layout passes. Make a symbolic breakpoint at UITableViewAlertForLayoutOutsideViewHierarchy to catch this in the debugger and see what caused this to occur, so you can avoid this action altogether if possible, or defer it until the table view has been added to a window.