【问题标题】:How to bind to Published property with private setter如何使用私有 setter 绑定到已发布的属性
【发布时间】:2023-01-20 21:43:10
【问题描述】:

这是我的数据模型:

@MainActor
class TestModel: ObservableObject {
    @Published private(set) var data = ""
    
    private func randomAlphaNumericString(length: Int) -> String {
        let allowedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
        let allowedCharsCount = UInt32(allowedChars.count)
        var randomString = ""

        for _ in 0 ..< length {
            let randomNum = Int(arc4random_uniform(allowedCharsCount))
            let randomIndex = allowedChars.index(allowedChars.startIndex, offsetBy: randomNum)
            let newCharacter = allowedChars[randomIndex]
            randomString += String(newCharacter)
        }

        return randomString
    }
    
    func update() {
        data = randomAlphaNumericString(length: 10)
    }
}

应用程序视图是:

import SwiftUI

struct TestView: View {
    @StateObject var model = TestModel()
    
    var body: some View {
        VStack {
            TestSubView(textData: $model.data)
            Button("Update") {
                model.update()
            }
        }
    }
}

其中子视图定义如下:

import SwiftUI

struct TestSubView: View {
    @Binding var textData: String
    
    var body: some View {
        Text("Data : \(textData)")
    }
}

使用此代码,由于模型字段数据的私有设置器,我得到了一个编译错误。我怎样才能与私人二传手呆在一起并使这种绑定起作用?应遵循的正确模式是什么?

【问题讨论】:

  • 哦...你想让TextSubView 更新data var 的值吗?如果没有,那么 @Binding 不是您在这里需要的。 @Binding 在您希望视图更新值并将该更新写回您的 view model 时使用。
  • 不,我只想用父视图中定义的 Observable 对象更新子视图。

标签: swiftui


【解决方案1】:

如果没有视图可以编辑data,那么您不需要绑定。只需将 data 的值作为 let 属性传递即可。 TestView 中包含的任何子视图都将在值发生变化时重新计算:

import SwiftUI

struct TestView: View {
    @StateObject var model = TestModel()
    
    var body: some View {
        VStack {
            TestSubView(textData: model.data)
            Button("Update") {
                model.update()
            }
        }
    }
}

struct TestSubView: View {
    let textData: String
    
    var body: some View {
        Text("Data : (textData)")
    }
}

【讨论】:

    【解决方案2】:

    我认为您根本不需要@Binding。看起来你TextSubView 没有更新文本。您只想确保它在文本更新时更新。

    所以像这样改变你的看法......

    import SwiftUI
    
    struct TestView: View {
        @StateObject var model = TestModel()
        
        var body: some View {
            VStack {
                TestSubView(textData: model.data)
                Button("Update") {
                    model.update()
                }
            }
        }
    }
    

    你的 TextSubView 是这样的......

    import SwiftUI
    
    struct TestSubView: View {
        let textData: String
        
        var body: some View {
            Text("Data : (textData)")
        }
    }
    

    这样做会删除代码中允许您的视图更新文本的任何内容。无论如何你没有做。

    【讨论】:

    • 伟大的思想,我的朋友,伟大的思想:D
    猜你喜欢
    • 1970-01-01
    • 2011-11-10
    • 1970-01-01
    • 2010-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    相关资源
    最近更新 更多