Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save ryanashcraft/7e408c3c2b21fb76c359fda60c86c531 to your computer and use it in GitHub Desktop.
Save ryanashcraft/7e408c3c2b21fb76c359fda60c86c531 to your computer and use it in GitHub Desktop.
manually managing special view's ID
import SwiftUI
@main
struct WindowPresentationFunApp: App {
@State var appState = AppState()
var body: some Scene {
WindowGroup {
RootView(appState: appState)
.onAppear {
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1)) {
appState.show = true
}
}
}
}
}
struct RootView: View {
var appState: AppState
var body: some View {
ZStack {
SpecialView()
.id(appState.specialViewID)
if appState.show {
Text("Some cool text")
}
}
}
}
struct SpecialView: View {
@State var viewModel = ViewModel()
var body: some View {
Text("Special stuff")
}
}
@Observable class AppState {
var show: Bool = false {
didSet {
specialViewID = UUID()
}
}
var specialViewID = UUID()
}
@Observable class ViewModel {
init() {
print("✅ View model was inited")
}
deinit {
print("❌ View model was deinited")
}
}
@ryanashcraft
Copy link
Author

By the way, I tested this on macOS with multiple windows. I think you probably want to initialize AppState once per window. Initially I thought all you'd have to do is move AppState to RootView, but that actually didn't have an effect. I followed this tip to initialize it an onAppear. It works, but feels like a hacky workaround that shouldn't be necessary. 🤷‍♂️

import SwiftUI

@main
struct WindowPresentationFunApp: App {
    var body: some Scene {
        WindowGroup {
            RootView()
        }
    }
}

struct RootView: View {
    @State var appState: AppState?

    var body: some View {
        ZStack {
            if let appState {
                SpecialView()
                    .id(appState.specialViewID)

                if appState.show {
                    Text("Some cool text")
                }
            }
        }
        .onAppear {
            appState = AppState()

            DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1)) {
                appState?.show = true
            }
        }
    }
}

struct SpecialView: View {
    @State var viewModel = ViewModel()

    var body: some View {
        Text("Special stuff")
    }
}

@Observable class AppState {
    var show: Bool = false {
        didSet {
            specialViewID = UUID()
        }
    }

    var specialViewID = UUID()

    init() {
        print("✅ App state was inited")
    }

    deinit {
        print("❌ App state was deinited")
    }
}

@Observable class ViewModel {
    init() {
        print("✅ View model was inited")
    }

    deinit {
        print("❌ View model was deinited")
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment