I've made a ViewModifier
for my app so that when it goes into .background
phase it shows a splash of an image. However, when a .sheet
or a .fullScreenCover
is presented it doesn't seem to be triggering the modifier or detecting scenePhase changes.
I've seen that you have to pass the environment from presentation to presentation which works for a 1-2 views, but if I want it to operate on the ViewModifier is it possible? Or is this a bug?
I feel like having to pass either .maskView()
to every screen or passing the @Environment()
or .environment()
to every view too seems wrong for Swift.
Main view
struct TestOverlay: View {
@State private var showSheet: Bool = false
var body: some View {
Button("Show sheet") {
showSheet = true
}
.sheet(isPresented: $showSheet) {
Button("Hide sheet") {
showSheet = false
}
}
.maskView()
}
}
Modifier
struct MaskingViewModifier: ViewModifier {
@Environment(\.scenePhase) private var scenePhase
@State private var currentPhase: ScenePhase = .active
func body(content: Content) -> some View {
ZStack {
content
.blur(radius: currentPhase == .active ? 0 : 5)
Color(.systemBackground)
.ignoresSafeArea()
.opacity(currentPhase == .active ? 0 : 0.4)
Image(systemName: "xmark")
.resizable()
.shadow(radius: 5)
.frame(width: 180, height: 180)
.opacity(currentPhase == .active ? 0 : 1)
}
.ignoresSafeArea()
.animation(.default, value: currentPhase)
.onChange(of: scenePhase) { phase in
switch phase {
case .active:
currentPhase = .active
case .inactive:
currentPhase = .inactive
case .background:
currentPhase = .background
@unknown default:
currentPhase = .active
}
}
}
}
Extension
extension View {
func maskView() -> some View {
return modifier(MaskingViewModifier())
}
}