0

使用 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() 在上述情况下不能正常工作吗?

4

0 回答 0