【问题标题】:Global vs Local in SwiftUISwiftUI 中的全局与本地
【发布时间】:2020-03-11 08:40:47
【问题描述】:
test view3 body, glabel selected = false
test view3, will show test view4
test view3 body, glabel selected = false
test view4 init, glabel selected = false, local selected = false
test view4 body, glabel selected = false, local selected = false
test view4, local toggle
test view4 body, glabel selected = false, local selected = true
test view4, global toggle
test view4 body, glabel selected = true, local selected = true
test view3 body, glabel selected = true
test view4 init, glabel selected = true, local selected = true
test view4 body, glabel selected = true, local selected = true
test view4, global toggle
test view4 body, glabel selected = false, local selected = true
test view3 body, glabel selected = false
test view4 init, glabel selected = false, local selected = false  // #1
test view4 body, glabel selected = false, local selected = true   // #2

这里是一些以下源代码的日志。 TestView4 有一个从全局初始化的本地状态值。当全局值改变时,testView 3&4 都刷新,test view4 init(#1) 和 test view4 body(#2) 有不同的值,为什么? testview4 的 UI 显示为 #2,我希望它是 #2,因为一旦 testview4 显示,我不希望全局值影响本地值。如何避免在全局值更改时测试 view4 init(#1),testview3 刷新,导致测试 view4 init(#1)?

class TestData: ObservableObject {
    static let shared = TestData()
    @Published var selected: Bool = false
}

struct TestView3: View {
    @ObservedObject var data = TestData.shared
    @State private var sheetShowing = false
    var body: some View {
        print("test view3 body, glabel selected = \(data.selected)"); return
        VStack {
            Text("Global").foregroundColor(data.selected ? .red : .gray).onTapGesture {
                self.data.selected.toggle()
            }.padding()
            Button(action: {
                self.sheetShowing = true
                print("test view3, will show test view4")
            }) { Text("Show TestView4") }.padding()
        }.sheet(isPresented: $sheetShowing) { TestView4(selected: self.data.selected) }
    }
}

struct TestView4: View {
    @ObservedObject var data = TestData.shared
    @State private var selected = false
    init(selected: Bool) {
        self._selected = State(initialValue: selected)
        print("test view4 init, glabel selected = \(data.selected), local selected = \(self.selected)")
    }
    var body: some View {
        print("test view4 body, glabel selected = \(data.selected), local selected = \(selected)"); return
        VStack {
            Text("Local").foregroundColor(selected ? .red : .gray).onTapGesture {
                self.selected.toggle()
                print("test view4, local toggle")
            }.padding()
            Text("Global").foregroundColor(data.selected ? .red : .gray).onTapGesture {
                self.data.selected.toggle()
                print("test view4, global toggle")
            }.padding()
        }
    }
}

【问题讨论】:

    标签: swiftui


    【解决方案1】:

    只要你插入这一行

     @ObservedObject var data = TestData.shared
    

    在结构体中,数据的每一次变化都会触发一次更新。

    测试自己:

    class T : ObservableObject {
    
        @Published var a = 1
        @Published var b = 2
    }
    
    struct ContentView: View {
    
        @EnvironmentObject var t : T
    
        init() {
            print("init")
        }
    
        var body: some View {
            print ("update")
            return Text("Hello, World!")
        }
    }
    

    以及场景委托中的测试调用:

     var t = T()
            let contentView = ContentView().environmentObject(t)
    
            Timer.scheduledTimer(withTimeInterval: 2, repeats: true) { (timer) in
                t.a += 1
            }
    

    【讨论】:

    • 当然我知道 ObservedObject 改变会触发视图更新。你不明白我的意思。不过还是谢谢。
    猜你喜欢
    • 2018-12-22
    • 1970-01-01
    • 2023-03-03
    • 1970-01-01
    • 2010-10-01
    • 2019-07-14
    • 2018-10-09
    • 1970-01-01
    • 2014-04-08
    相关资源
    最近更新 更多