问题
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