2021 SWIFT 1 and 2 both:
IMPORTANT THING! If you search for this hack, probably you doing something wrong! Please, read this block before you read hack solution!!!!!!!!!!
Your UI wasn’t updated automatically because of you miss something
important.
- Your ViewModel must be a
class
wrapped intoObservableObject
/ObservedObject
- Any field in ViewModel must be a
STRUCT
. NOT ACLASS
!!!! Swift UI does not work with classes!- Must be used modifiers correctly (state, observable/observedObject, published, binding, etc)
- If you need a
class
property in your View Model (for some reason) – you need to mark it asObservableObject
/Observed
object and assign them into View’s object !!!!!!!! insideinit()
ofView
. !!!!!!!- Sometimes is needed to use hacks. But this is really-really-really exclusive situation! In most cases this wrong way! One more time: Please, use
struct
s instead of classes!Your UI will be refreshed automatically if all of written above was used correctly.
Sample of correct usage:
struct SomeView : View {
@ObservedObject var model : SomeViewModel
@ObservedObject var someClassValue: MyClass
init(model: SomeViewModel) {
self.model = model
//as this is class we must do it observable and assign into view manually
self.someClassValue = model.someClassValue
}
var body: some View {
//here we can use model.someStructValue directly
// or we can use local someClassValue taken from VIEW, BUT NOT value from model
}
}
class SomeViewModel : ObservableObject {
@Published var someStructValue: Bool
var someClassValue: MyClass = NewMyClass //myClass : ObservableObject
}
And the answer on topic question.
(hacks solutions – prefer do not use this)
Way 1: declare inside of view:
@State var updater: Bool = false
all you need to update is toogle() it: updater.toogle()
Way 2: refresh from ViewModel
Works on SwiftUI 2
public class ViewModelSample : ObservableObject
func updateView(){
self.objectWillChange.send()
}
}
Way 3: refresh from ViewModel:
works on SwiftUI 1
import Combine
import SwiftUI
class ViewModelSample: ObservableObject {
private let objectWillChange = ObservableObjectPublisher()
func updateView(){
objectWillChange.send()
}
}