ViewModifier: Pass in ScenePhase or get from @Environment?

I have two view modifiers that work identically in my tests, but I'm concerned I'm missing some case where they wouldn't.

Which is better and why: To pass in the ScenePhase from the parent view or to call it directly from the environment?


extension View {
    func reportPhaseChange(phase: ScenePhase) -> some View {
        modifier(ReportPhaseChange(phase: phase))
    }
    
    func reportPhaseChange() -> some View {
        modifier(ReportPhaseChange2())
    }
}

struct ReportPhaseChange: ViewModifier {
    var phase:ScenePhase
    
    func body(content: Content) -> some View {
        content.onChange(of: phase) { _, newPhase in
            switch newPhase {
            case .active:
                print("going active")
            case .background:
                print("going background")
            case .inactive:
                print("going inactive")
            @unknown default:
                fatalError()
            }
        }
    }
}
    

        
struct ReportPhaseChange2: ViewModifier {
    @Environment(\.scenePhase) var phase
    
    func body(content: Content) -> some View {
        content.onChange(of: phase) { _, newPhase in
            switch newPhase {
            case .active:
                print("going active")
            case .background:
                print("going background")
            case .inactive:
                print("going inactive")
            @unknown default:
                fatalError()
            }
        }
    }
}
Answered by DTS Engineer in 847872022

Either approach is perfectly fine and is one of the many powers of ViewModifiers. Keep in mind that the interpretation of the value depends on where it’s read from either from a view instance or within an App instance,

Accepted Answer

Either approach is perfectly fine and is one of the many powers of ViewModifiers. Keep in mind that the interpretation of the value depends on where it’s read from either from a view instance or within an App instance,

Thanks! Good to know they're both valid.

Since this is in a ViewModifier, which couldn't attach to a WindowGroup, there might be some protection? But you never know. Good to a mention in any documentation I write for it.

Perhaps then it is safer to not let one be passed in?

Presumably any Views the ViewModifier would add (like a conditional overlay) would have their own ScenePhases, but would there ever be a situation where the modifier and the view it modifies would have different ScenePhases? Is a view modifier in the same Scene as it's parent view or it's own thing?

ViewModifier: Pass in ScenePhase or get from @Environment?
 
 
Q