SwiftUI笔记

@Published 标记对象定义的属性变更可以被监听,当对应字段变化时会触发对象 objectWillChange 通知,订阅了该属性的View也会收到值改变的通知

/// A type that publishes a property marked with an attribute.
///
/// Publishing a property with the `@Published` attribute creates a publisher of this type. You access the publisher with the `$` operator, as shown here:
///
///     class Weather {
///         @Published var temperature: Double
///         init(temperature: Double) {
///             self.temperature = temperature
///         }
///     }
///
///     let weather = Weather(temperature: 20)
///     cancellable = weather.$temperature
///         .sink() {
///             print ("Temperature now: \($0)")
///     }
///     weather.temperature = 25
///
///     // Prints:
///     // Temperature now: 20.0
///     // Temperature now: 25.0
///

 @ObservedObject 和 @State 类似,需要修饰的属性需要实现了 ObservableObject,@ObservedObject监听属性值的@Published属性变化会随属性修改则改变UI,@State是属性值自身发生变化时会影响UI呈现

class ObjectClass: ObservableObject {
    @Published var name: String
    @Published var source: Int
    init(name: String = "", source: Int = 0) {
        self.name = name
        self.source = source
    }
}

struct ContentView: View {
    
    @ObservedObject var data = ObjectClass()
    
    var body: some View {
        VStack {
            Image(systemName: "globe")
                .imageScale(.large)
                .foregroundColor(.accentColor)
                .onTapGesture {
                    print("---> \(data.name)")
                    data.name = "99999"
                }
            Text(data.name)
                
            SubView()
                .environmentObject(data)
        }
        .padding()
    }
}

struct SubView: View {
    @EnvironmentObject var data: ObjectClass
    var body: some View {
        TextField("输入框", text: $data.name)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

 

 

父View 以 @State 声明的属性 @State var param: DataType,可以在子View初始化的时候以 $param 给到子View,子View 通过 @Banding 关键字取得 param 数据关联,在值变化时进行相应的改变

var body: some View {
        HStack {
            Image(uiImage: UIImage(named: icon.isSelected ? "common_item_select" : "common_item_unselect")!)
                .resizable()
                .aspectRatio(contentMode: .fit)
                .frame(width: 24.0~, height: 24.0~)
            Image(uiImage: icon.iconImage ?? UIImage())
                .resizable()
                .aspectRatio(contentMode: .fit)
                .frame(width: 48.0~, height: 48.0~)
            Image(uiImage: UIImage(named: "edit_arrow")!)
                .resizable()
                .aspectRatio(contentMode: .fit)
                .frame(width: 24.0~, height: 24.0~)
            ZStack {
                Image(uiImage: icon.originImage ?? UIImage())
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(width: 48.0~, height: 48.0~)
                Image(uiImage: UIImage(named: "edit_edit")!)
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(width: 16.0~, height: 16.0~)
            }
            HStack {
                Image(uiImage: UIImage(named: "edit_install")!)
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(width: 16.0~, height: 16.0~)
                Text("Install".localized)
            }
            // 属性配置是存在顺序依赖的,下一个配置是针对上一个返回,例如下面如果先设置高再设置内边距,则变成了再原有高度32.0基础上再增加内边距
            .padding(EdgeInsets(top: 8.0~, leading: 8.0~, bottom: 8.0~, trailing: 8.0~))
            .frame(height: 32.0~)
            .background(Color(PRUIUtils.sharedInstance().redColor))
            .cornerRadius(15.0~)
        }
    }

 控件元素没有铺满控件,这个时候点击子控件才会触发 onTapGesture 事件,但是如果设置上 background,那么在确定事件响应对象时,则会落到预期的控件上面去了,一定要记得设置背景(透明背景无效)

 

SwiftUI组件 设置了 id ,如果 id 为Builder中随机生成,那么可能将会触发view的不断重建

posted @ 2023-03-03 10:13  雨筱逸悠  阅读(28)  评论(0编辑  收藏  举报