SwiftUI: fullScreenCover equivalent for macOS apps?

Viewed 312

I am writing a cross-platform SwiftUI app that needs to present a password prompt if the user wishes to "lock" the application. The lock screen should cover all views in the application until the user successfully authenticates. On iOS I'm able to do this using the fullScreenCover method like this:

.fullScreenCover(isPresented: $isLocked, content: {
        ApplicationLockView(viewModel: ApplicationLockViewModel())
    })

This works great. However, this method is unavailable on macOS. Is there an equivalent way of accomplishing this on macOS?

1 Answers

fullScreenCover(isPresented:onDismiss:content:) does support in Mac Catalyst 14.0+.

Enable the mac support for the target:

enter image description here

Source used for testing on mac:

struct ContentView: View {
    @State private var isPresented = false
    var body: some View {
        Button("Present") {
            isPresented.toggle()
        }
        .fullScreenCover(isPresented: $isPresented) {
            ModalView()
        }
    }
}
struct ModalView: View {
    @Environment(\.presentationMode) var presentationMode
    var body: some View {
        Button("Dismiss") {
            presentationMode.wrappedValue.dismiss()
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(Color.blue)
        .edgesIgnoringSafeArea(.all)
    }
}

Using Move Edge Transition:

struct ContentView: View {
    @State private var isPresented = false
    var body: some View {
        ZStack {
            Button("Present", action: {
                withAnimation(.linear) {
                    self.isPresented.toggle()
                }
            })
            
            if isPresented {
                ModalView(isPresented: self.$isPresented).transition(.move(edge: .bottom))
            }
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
    }
}

struct ModalView: View {
    @Binding var isPresented: Bool
    var body: some View {
        ZStack {
            Rectangle()
                .fill(Color.blue)
                .frame(maxWidth: .infinity, maxHeight: .infinity)
            VStack {
                Button("Dismiss",action: {
                    withAnimation(.linear) {
                        self.isPresented.toggle()
                    }
                })
            }
        }
    }
}
Related