Here is my data model:
@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)
}
}
And the application view is:
import SwiftUI
struct TestView: View {
@StateObject var model = TestModel()
var body: some View {
VStack {
TestSubView(textData: $model.data)
Button("Update") {
model.update()
}
}
}
}
where a subview is defined as follows:
import SwiftUI
struct TestSubView: View {
@Binding var textData: String
var body: some View {
Text("Data : \(textData)")
}
}
With this code I get a compilation error because of a private setter for a model field data. How can I stay with a private setter and get this binding to work? What is the correct pattern to follow?
>Solution :
I think you don’t need a @Binding here at all. It looks like you TextSubView is not updating the text. You just want to make sure that it updates when the text updates.
So change your view like this…
import SwiftUI
struct TestView: View {
@StateObject var model = TestModel()
var body: some View {
VStack {
TestSubView(textData: model.data)
Button("Update") {
model.update()
}
}
}
}
And your TextSubView like this…
import SwiftUI
struct TestSubView: View {
let textData: String
var body: some View {
Text("Data : \(textData)")
}
}
Doing this removes anything in the code that allows your view to update the text. Which you weren’t doing anyway.