选择(取消)选择项目时的 SwiftUI 回调

Dim*_*dui 3 swift swiftui

我有以下列表:

List(selection: self.$selectionKeeper) {
    ForEach(self.items, id: \.self) { name in
        Text(name)
    }
}
.environment(\.editMode, .constant(.active))
Run Code Online (Sandbox Code Playgroud)

每次选择(取消)选择某个项目时如何获得回调?我知道我可以倾听 的变化selectionKeeper,但我认为可能有更好的方法

paw*_*222 5

是的,最简单的方法是使用onChange(或onReceive在 iOS 13 中)监视以下更改selectionKeeper

List(selection: self.$selectionKeeper) {
    ForEach(0..<5, id: \.self) { item in
        Text("\(item)")
    }
}
.environment(\.editMode, .constant(.active))
.onChange(of: selectionKeeper) { selectedItems in
    print(selectedItems)
}
Run Code Online (Sandbox Code Playgroud)

如果您想以其他方式执行此操作,您可以创建自定义绑定:

struct ContentView: View {
    @State private var selectionKeeper = Set<Int>()
    
    var body: some View {
        List(selection: .init(
            get: {
                selectionKeeper
            },
            set: {
                selectionKeeper = $0
                selectionCallback($0)
            }
        )) {
            ForEach(0..<5, id: \.self) { item in
                Text("\(item)")
            }
        }
        .environment(\.editMode, .constant(.active))
    }
    
    func selectionCallback(_ selectedItems: Set<Int>) {
        print(selectedItems)
    }
}
Run Code Online (Sandbox Code Playgroud)

您还可以将绑定提取为计算属性:

var listBinding: Binding<Set<Int>> {
    .init(
        get: {
            selectionKeeper
        },
        set: {
            selectionKeeper = $0
            selectionCallback($0)
        }
    )
}
Run Code Online (Sandbox Code Playgroud)
List(selection: listBinding) { ... }
Run Code Online (Sandbox Code Playgroud)

onChange当您只需要对特定变量的更改做出反应时,该解决方案更简单、更有用。但是,通过自定义绑定,您可以获得更大的灵活性(您可以更改 和getset