Why does this SwiftUI Picker code not work?

≯℡__Kan透↙ 提交于 2021-01-19 05:56:29

问题


Xcode: 11.2.1

The code below is for a simple form with two components; a Picker (to select a letter) and a Text (to display the selected letter). The code compiles and runs but, when a letter is selected it does not appear in the "Selected..." text. In addition, Xcode displays a (spurious?) run time warning the first time (only) a letter is selected..

struct ContentView: View {

    @State private var letter = ""
    private let letters = ["Alpha", "Bravo", "Charlie"]

    var body: some View {
        NavigationView {
            Form {
                Picker("Select a letter", selection: $letter) {
                    ForEach(0..<letters.count) {
                        Text(self.letters[$0])
                    }
                }
                Text("Selected letter: \(letter)")
            }
            .navigationBarTitle("Main Menu")
        }
    }
}

For info: the run time warning:

[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. Table view: <_TtC7SwiftUIP33_BFB370BA5F1BADDC9D83021565761A4925UpdateCoalescingTableView: 0x7f8b33872600; baseClass = UITableView; frame = (0 0; 414 896); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = ; layer = ; contentOffset: {0, -140}; contentSize: {414, 205.33333333333337}; adjustedContentInset: {140, 0, 34, 0}; dataSource: <_TtGC7SwiftUIP10$10f5cd23419ListCoreCoordinatorGVS_20SystemListDataSourceOs5Never_GOS_19SelectionManagerBoxS2___: 0x7f8b33407a70>>


回答1:


ForEach types inside Picker should be aligned with selection type.

Here is a corrected code that should work for you:

@State private var letter = ""
private let letters = ["Alpha", "Bravo", "Charlie"]

var body: some View {
    NavigationView {
        Form {
            Picker("Select a letter", selection: $letter) {
                ForEach(letters, id: \.self) { option in
                    Text(option)
                }
            }
            Text("Selected letter: \(letter)")
        }
        .navigationBarTitle("Main Menu")
    }
}



回答2:


Just for the record, I'm answering my own question based on the accepted answer above and my increased knowledge as a result of that answer. In the question I was not selecting a letter from the array but the index of the letter in the array. So, based on the insight, an alternative working solution might be:

struct ContentView: View {

    @State private var letterIndex = 0
    private let letters = ["Alpha", "Bravo", "Charlie"]

    var body: some View {
        NavigationView {
            Form {
                Picker("Select a letter", selection: $letterIndex) {
                    ForEach(0..<letters.count) { index in
                        Text(self.letters[index])
                    }
                }
                Text("Selected letter: \(letters[letterIndex])")
        }
        .navigationBarTitle("Main Menu")
    }
}


来源:https://stackoverflow.com/questions/58880536/why-does-this-swiftui-picker-code-not-work

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!