NEW: Start my new Ultimate Portfolio App course with a free Hacking with Swift+ trial! >>

@StateObject on iOS 13

Forums > SwiftUI

Hello, we realized today that our app was targeting iOS 14, and changed it to iOS 13. We found out we are not able to use StateObject on iOS 13, and some problems arose. This is what we have:

AlertState.swift

final class CardState: ObservableObject {
    static let shared = CardState()

    @Published var shouldShowCard = false

    private init() {}

    // Some other methods and variables
}

Then, we use it like this:

ContentView.swift

struct ContentView: View {
    @StateObject var cardState = CardState.shared

    var body: some View {
        ZStack(alignment: .center) {
            if cardState.shouldShowCard {
                Card()
            }
        }
    }
}

Card.swift

struct Card: View {
    @StateObject var cardState = CardState.shared

    var body: some View {
        // View
    }
}

AlertState holds more data, such as the text we show in the card. The card can be triggered from any screen of the app.

So, we targeted iOS 13 and replaced StateObject with ObservedObject, but then it stopped animating when the card gets hidden by switching shouldShowCard to false, the View just disappears. What should we use in order to achieve what we used to have when using StateObject? We are a bit lost and tried everything we found.

Thanks in advance.

   

Why are you wanting to target iOS 13 and not 14!

@StateObject was only intoduced in 14 therfore not working in early version. therefore would look at keeping at iOS 14 and above.

   

You have to user @ObservedObject instead if you are using iOS 13.

ObservedObject should be injected into the view. I also don't know why you are using @StateObject in Card view. Card view depends on the ContentView, so only ContentView should be creating an instance of CardState. It will also enable you to remove that singleton in CardView. Even if you were targeting iOS 14, it would still make sense using @ObservedObject in the Card view rather than using singletons.

So,

struct ContentView: View {
    @ObservedObject var cardState: CardState

    var body: some View {
        ZStack(alignment: .center) {
            if cardState.shouldShowCard {
                Card(cardState: cardState)
            }
        }
    }
}

struct Card: View {
    @ObservedObject var cardState: CardState

     ...
 }

// then when you initialize ContentView
ContentView(cardState: CardState())

Be aware though, that using ObservedObject can sometimes cause some unexpected side effects, which is why they introduced @StateObject.

   

Hacking with Swift is sponsored by Stream

SPONSORED Check out Stream's cross-platform open source chat SDK on GitHub! Write once and deploy your app with fully featured chat UI on iOS and macOS.

Go to GitHub

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.