Jorgen
Jorgen

Reputation: 475

SwiftUI force child view to redraw

I have a modal view with a child view, with in itself has another child view. When I rotate the device, the first child view need to get redrawn to pass new GeometricReader data to the last child.

I'm detecting the rotation by Notification Center in the view model

    @objc func updateView(_ : Notification) {
        self.refresh.toggle()
        self.objectWillChange.send()
        }

The view model has two properties.

        @Published var objectWillChange = ObservableObjectPublisher()
        @Published var refresh: Bool

In the view I have a @observedObject vm, but when the vm changes the view doesn't redraw. The first child need to redraw to send it's size to the second child for some line drawings that need to be re-aligned.

[Edit]

struct StackView: View {
@ObservedObject var vm = ViewModel()

var body: some View {
    
    Color.white
    VStack {
        Spacer()
        VStack {
            Text("Hello StackView")
            View2()
        }
    }
}
}

extension StackView {
final class ViewModel: ObservableObject {
    
    init() {
        NotificationCenter.default.addObserver(self, selector: #selector(updateView(_:)), name: UIDevice.orientationDidChangeNotification, object: nil)
    }
    
    deinit {
        NotificationCenter.default.removeObserver(self, name: UIDevice.orientationDidChangeNotification, object: nil)
    }
    
    @objc func updateView(_ notification: Notification) {
        self.objectWillChange.send()
    }
}
}

struct View2: View {

var body: some View {
    Text("Hello view 2")
        .overlay(GeometryReader { geo in
            Color.clear
                .onAppear {
                    print(geo.frame(in: .global))
                }
        })
}
}

Upvotes: 1

Views: 2073

Answers (1)

Asperi
Asperi

Reputation: 258345

    @Published var objectWillChange = ObservableObjectPublisher()

remove this line. ObservableObject has default implementation of publisher for objectWillChange property, so just use it, like

@objc func updateView(_ : Notification) {
   self.objectWillChange.send()
}

and if you don't have special meaning for var refresh: Bool then it is also not needed.

Upvotes: 1

Related Questions