Swift UI @Binding 代码实现
import SwiftUI final class Box<T> : ObservableObject { // 这个注解不加,那就玩死了也不会更新视图 @Published var val: T init(val: T) { self.val = val } } struct StarRating: View { // 个人理解类似Java的Spring容器管理,用更大的容器中的一个小容器来装共享级别更低的 @EnvironmentObject private var box: Box<Int> // @Binding对象的实际类型, @State个人理解是在注解的地方还是原来的对象,只是在传递过去的控件中创建了新的Binding对象 private var rating: Binding<Int> { Binding { // 实际存储值的地方 return box.val } set: { newValue in // 实际更新值的地方 box.val = newValue } } private let maxRating = 5 var body: some View { HStack { ForEach(1..<maxRating + 1, id: \.self) { value in Image(systemName: "star") .symbolVariant(value <= rating.wrappedValue ? .fill : .none) .foregroundColor(.accentColor) .onTapGesture { if value != rating.wrappedValue { rating.wrappedValue = value } else { rating.wrappedValue = 0 } } } } } } struct StarRating_Previews: PreviewProvider { static var previews: some View { ForEach(1..<6) { val in StarRating() .environmentObject(Box(val: val)) } } }
参考文档:https://developer.apple.com/tutorials/swiftui-concepts/defining-the-source-of-truth-using-a-custom-binding