Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update a SwiftUI view state from outside (UIViewController for example)

Tags:

I have a SwiftUI view:

struct CatView : View {      @State var eyesOpened: Bool = false      var body: some View {        Image(uiImage: eyesOpened ? #imageLiteral(resourceName: "OpenedEyesCat") : #imageLiteral(resourceName: "ClosedEyesCat"))     } } 

I'm trying to integrate it with in a regular UIViewController.

let hostingVC = UIHostingController<CatView>(rootView: cat) addChild(hostingVC) view.addSubview(hostingVC.view) hostingVC.view.pinToBounds(of: view) 

Now in the UIViewController if I try to set the eyesOpened property I get a

Thread 1: Fatal error: Accessing State<Bool> outside View.body

How are we supposed to make this work? Are SwiftUI views not supposed to work in this scenario?

like image 338
Nuno Gonçalves Avatar asked Jun 22 '19 20:06

Nuno Gonçalves


People also ask

How do I refresh a view in SwiftUI?

To add the pull to refresh functionality to our SwiftUI List, simply use the . refreshable modifier. List(emojiSet, id: \. self) { emoji in Text(emoji) } .

How do I change my state variable in SwiftUI?

In case we have to modify state when another state is known, we can encapsulate all those states in ObservableObject and use onReceive to check the state we want to act on. Modifying state during view update, this will cause undefined behavior.

Does SwiftUI have Viewcontrollers?

SwiftUI works seamlessly with the existing UI frameworks on all Apple platforms. For example, you can place UIKit views and view controllers inside SwiftUI views, and vice versa.

What is a state in SwiftUI?

SwiftUI manages the storage of a property that you declare as state. When the value changes, SwiftUI updates the parts of the view hierarchy that depend on the value. Use state as the single source of truth for a given value stored in a view hierarchy.


1 Answers

@State is the wrong thing to use here. You'll need to use @ObservedObject.

@State: Used for when changes occur locally to your SwiftUI view - ie you change eyesOpened from a toggle or a button etc from within the SwiftUI view it self.

@ObservedObject: Binds your SwiftUI view to an external data source - ie an incoming notification or a change in your database, something external to your SwiftUI view.

I would highly recommend you watch the following WWDC video - Data Flow Through SwiftUI

like image 135
Robert J. Clegg Avatar answered Oct 21 '22 11:10

Robert J. Clegg