Search code examples
iosswiftmacosswiftui

SwiftUI: fullScreenCover equivalent for macOS apps?


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?


Solution

  • 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()
                        }
                    })
                }
            }
        }
    }