问题
I want to set the selected row in a List programmatically.
In my example below via 2 Buttons.
struct ContentView: View {
@State private var selection = 2
var body: some View {
VStack {
List() {
//List(selection: $selection) {. // does not compile
Text("Line 0").tag(1)
Text("Line 1").tag(1)
Text("Line 2").tag(2)
Text("Line 3").tag(3)
Text("Line 4").tag(4)
Text("Line 5").tag(5)
}
.listStyle(SidebarListStyle())
Text("Selected Item :\(self.selection)")
HStack {
Button(action: {if (self.selection < 5 ) { self.selection += 1 }} ) {Text("⬇︎")}
Button(action: {if (self.selection > 0 ) { self.selection -= 1 }} ) {Text("⬆︎")}
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
trying to make the List selectable like this:
List(selection: $selection)
does not compile.
Compiler complains: Unable to infer complex closure return type; add explicit type to disambiguate
回答1:
Selection type must be optional. Find below fixed code.
struct TestListSelectionOnAction: View {
@State private var selection: Int? = 2 // optional !!
var body: some View {
VStack {
List(selection: $selection) {
Text("Line 0").tag(0)
Text("Line 1").tag(1)
Text("Line 2").tag(2)
Text("Line 3").tag(3)
Text("Line 4").tag(4)
Text("Line 5").tag(5)
}
.listStyle(SidebarListStyle())
Text("Selected Item :\(self.selection ?? -1)")
HStack {
Button(action: {
if (self.selection! < 5 ) { self.selection! += 1 }} ) {Text("⬇︎")}
Button(action: {
if (self.selection! > 0 ) { self.selection! -= 1 }} ) {Text("⬆︎")}
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
回答2:
It won't compile because the tags are not unique. You are setting tag 1 twice. It can not identify the value, thats why List(selection: $selection) does not work either.
List() {
//List(selection: $selection) {. // should compile now
Text("Line 0").tag(0)
Text("Line 1").tag(1)
Text("Line 2").tag(2)
Text("Line 3").tag(3)
Text("Line 4").tag(4)
Text("Line 5").tag(5)
}
来源:https://stackoverflow.com/questions/61838352/swiftui-selecting-a-row-in-a-list-programmatically