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

 

posted @ 2023-06-01 12:09  gabin  阅读(92)  评论(0编辑  收藏  举报