How to remove environmentObject after dismiss View

39 Views Asked by At

I have a View like this:

    struct MainView: View{
    @EnvironmentObject var appModel: AppDataModel
    @State var localAppDataModel: AppDataModel! = AppDataModel()
    var body: some View{
        VStack {
            ContentView()
    }
         Button(action: {
            appModel.dismissAR()
        },
               label: {
            Text(LocalizedString.close)
                .modifier(VisualEffectRoundedCorner())
        })
        .environmentObject(localAppDataModel)
        .onDisappear{
            localAppDataModel.objectCaptureSession?.cancel()
            localAppDataModel.photogrammetrySession?.cancel()
            localAppDataModel.objectCaptureSession = nil
            localAppDataModel.photogrammetrySession = nil
            localAppDataModel.scanFolderManager = nil
            localAppDataModel.showPreviewModel = false
            localAppDataModel.orbit = .orbit1
            localAppDataModel.orbitState = .initial
            localAppDataModel.isObjectFlipped = false
            localAppDataModel = nil
        }
    }

I present this view in UIKIt with this func:

public static func present(viewC: UIViewController){
    let controller = UIHostingController(rootView: MainView(appModel: .init()))
    mainController = controller
    mainController?.modalPresentationStyle = .fullScreen
    guard let mainController else { return }
    viewC.present(mainController, animated: true, completion: nil)
}
var mainController: UIHostingController<MainView>?

When I dismiss

MainView

public class AppDataModel: ObservableObject, Identifiable {
....
    func dismissAR(){
        mainController?.dismiss(animated: true)
    }
....
   }
    

my app crash because localAppDataModel become nil. How can I dismiss MainView and deallocate/remove localdaAppDataModel environmentObject?

1

There are 1 best solutions below

0
malhal On

Since you have a ObservableObject you can use @StateObject var model = AppDataModel() which will init it once and deinit it on disappear automatically, including clearing all of its properties.

FYI if you decide to upgrade from Combine's ObservableObject to use @Observable then you need to make an optional @State var model: AppDataModel? and init it yourself in onAppear and set it nil in onDisappear. Bit more effort but you get tighter invalidation of your Views since it can track the object's individual properties rather that the whole object.