简体   繁体   中英

@State not updating SwiftUI view when changed in mutating function and initialiser

I have tried out different ways by which @State can be updated in a SwiftUI view. There are approaches where a state change updates the related view whereas in some it does not.

@State change updates view

@State var bodyText: String = "Hello swift"

var body: some View {
    Text(bodyText)
        .onAppear(perform: triggerTextUpdate)
}

private func triggerTextUpdate() {
    DispatchQueue.main.asyncAfter(deadline: .now()+3) {
        bodyText = "Hello I am future swift"
    }
}

@State changes not updating the view

1. @State changed from initializer

@State var bodyText: String = "Hello swift"
init() {
    triggerTextUpdate()
}

var body: some View {
    Text(bodyText)
}

private func triggerTextUpdate() {
    DispatchQueue.main.asyncAfter(deadline: .now()+3) {
        bodyText = "Hello I am future swift"
    }
}

2. @State changed from mutating function

@State var bodyText: String = "Hello swift"
private let somePublishSubject = PublishSubject<String, Never>()
private var subscriptions = Set<AnyCancellable>()

init() {
    setUpBinding()
}

var body: some View {
    Text(bodyText)
}

mutating func setUpBinding() {
    somePublishSubject.sink { [self] text in
        self.bodyText = text
    }.store(in: &subscriptions)
}

When the somePublishSubject gets invoked and alters the bodyText state, the view does not update.

There is not much documentation on SwiftUI which makes understanding why the view updation and @State changes become more confusing. Any explanation for this behaviour will be really helpful.

The doc says it very clearly.

You should only access a state property from inside the view's body, or from methods called by it. For this reason, declare your state properties as private, to prevent clients of your view from accessing them. It is safe to mutate state properties from any thread.

it means you are not allowed to change state in your init , or somePublishSubject.sink

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM