Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to make a modal non-dismissible in SwiftUI?

Tags:

swiftui

I am creating an App where the login / register part is inside a modal, which is shown if the user is not logged in.

The problem is, that the user can dismiss the modal by swiping it down...

Is it possible to prevent this?

var body: some View {
    TabView(selection: $selection) {
        App()
    }.sheet(isPresented: self.$showSheet) { // This needs to be non-dismissible
        LoginRegister()
    }
}

Second example:

I am using a modal to ask for information. The user should not be able to quit this process except by dismissing the modal with save button. The user has to input information before the button works. Unfortunately the modal can be dismissed by swiping it down.

Is it possible to prevent this?

like image 413
krjw Avatar asked Aug 07 '19 16:08

krjw


People also ask

How do I dismiss a popup in SwiftUI?

Any view can read its presentation mode using @Environment(\. presentationMode) , and calling wrappedValue. dismiss() on that will cause the view to be dismissed. The other option is to pass a binding into the view that was shown, so it can changing the binding's value back to false.

How do I show modal SwiftUI?

The action of the button toggles the state variable. To tell SwiftUI you want to display a modal, you call sheet(isPresented:onDismiss:content:) .

What is .sheet SwiftUI?

SwiftUI's sheets are used to present new views over existing ones, while still allowing users to drag down to dismiss the new view when they are ready.


1 Answers

iOS 15 and later:

Use .interactiveDismissDisabled(true) on the sheet, that's all.

Prev iOS 15:

You can try to do this by using a highPriorityGesture. Of course the blue Rectangle is only for demonstration but you would have to use a view which is covering the whole screen.

struct ModalViewNoClose : View {
    @Environment(\.presentationMode) var presentationMode
    
    let gesture = DragGesture()
    
    var body: some View {
        
        Rectangle()
            .fill(Color.blue)
            .frame(width: 300, height: 600)
            .highPriorityGesture(gesture)
            
            .overlay(
                VStack{
                    Button("Close") {
                        self.presentationMode.value.dismiss()
                    }.accentColor(.white)
                    Text("Modal")
                        .highPriorityGesture(gesture)
                    TextField("as", text: .constant("sdf"))
                        .highPriorityGesture(gesture)
                } .highPriorityGesture(gesture)
        )
            .border(Color.green)
    }
}
like image 94
Marc T. Avatar answered Oct 30 '22 08:10

Marc T.