使用 Swift5.2.3、iOS14.4.2、XCode12.4、
在 SwiftUI中使用.sheet
修饰符一开始让我感到很兴奋,因为它似乎是一种显示模态表的简单有效的方式。
然而,在现实世界的应用程序中,事实证明它.sheet
几乎可以集成。
这是发现的两个错误(其中包括......):
错误 1:具有 DefaultPickerStyle 的选取器在工作表的 SegmentPicker 内时不起作用
错误 2:工作表不会偶尔关闭(请参阅我创建的这个 Stackoverlow 问题)
现在让我们关注错误 Nr1:“在工作表的 SegmentPicker 内时,具有 DefaultPickerStyle 的选取器不起作用”。
我的意思可以在这个例子中得到最好的体现。这是真实世界应用程序的摘录。(是的,我需要放置这么多视图,因为普通的教科书示例工作得非常好 - 但一旦它变得更复杂一点......)。
请注意,“可怕的孩子”真的是这样.pickerStyle(DefaultPickerStyle())
!(您会在名为SettingsView
.
如果我用 - 替换样式,.pickerStyle(MenuPickerStyle())
那么应用程序工作得很好。
有什么问题DefaultPickerStyle()
???
请参阅此处说明问题的两个视频:
视频 1:FAULT 显示DefaultPickerStyle()
(您会看到.onChange(of: categoryIndex) { (idx) in ...}
从未使用此选择器样式调用...)
视频 2:正确的节目MenuPickerStyle()
import SwiftUI
@main
struct TestKOS005App: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
ContentView 如下所示:
enum THSheetSelection: Hashable, Identifiable {
case infoSettings
var id: THSheetSelection { self }
}
struct ContentView: View {
@State var sheetState: THSheetSelection?
var body: some View {
VStack {
Text("Hello, world!")
.padding()
Button("Show Settings Sheet") {
sheetState = .infoSettings
}
}
.sheet(item: $sheetState) { state in
switch state {
case .infoSettings:
InfoSettingsView()
}
}
}
}
InfoSettingsView 如下所示:
struct InfoSettingsView: View {
@Environment(\.presentationMode) var presentationMode
@State private var segmentSelection = 0
@State private var infoShown = false
var body: some View {
NavigationView {
VStack {
Picker("", selection: $segmentSelection) {
Text("Info").tag(0)
Text("Settiongs").tag(1)
}
.pickerStyle(SegmentedPickerStyle())
.background(Color.blue)
.padding()
switch segmentSelection {
case 0:
InfoView()
case 1:
SettingsView()
default:
InfoView()
}
}
.navigationBarTitle("Info & Settings")
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button(action: {
presentationMode.wrappedValue.dismiss()
}) {
Text("Done")
}
}
}
.onAppear {
segmentSelection = 0
}
}
}
}
InfoView 如下所示:
struct InfoView: View {
@Environment(\.presentationMode) var presentationMode
let versionNr: String = (Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String) ?? ""
let buildNr: String = (Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") as? String) ?? ""
var body: some View {
VStack {
Form {
Section(header: Text("App Info")) {
HStack {
Text("App Version")
Spacer()
Text("v\(versionNr) (\(buildNr))")
}
}
}
.ignoresSafeArea()
Spacer()
}
}
}
SettingsView 如下所示:
struct SettingsView: View {
@State private var categoryIndex = 0
var categorySelection = ["Choice 1", "Choice 2", "Choice 3", "Choice 4"]
var body: some View {
VStack {
Form {
Section(header: Text(LocalizedStringKey("InterDeviceCommKey"))) {
Picker(selection: $categoryIndex, label: Text(LocalizedStringKey("TechChoiceKey"))) {
ForEach(0 ..< categorySelection.count, id: \.self) { idx in
Text(categorySelection[idx]).tag(idx)
}
}
.pickerStyle(DefaultPickerStyle()) // does NOT behave correctly
// .pickerStyle(MenuPickerStyle()) // does behave correctly
.onChange(of: categoryIndex) { (idx) in /// ????????? why this never gets called with DefaultPickerStyle() ?????????
print("categoryChanged to index \(idx)")
}
}
Section(header: Text("Selected Choice")) {
HStack {
Text("My choice")
Spacer()
Text("\(categorySelection[categoryIndex])")
}
}
.ignoresSafeArea()
}
Spacer()
}
}
}
知道为什么 SwiftUI.sheet
的 DefaultPickerStyle() 在上述情况下不能正常工作吗?