DEV Community

loading...
Cover image for SwiftUI full screen modal

SwiftUI full screen modal

Tamas Dancsi
iOS and front-end dev. I try to think before coding, sometimes it works :)
Updated on ・2 min read

SwiftUI is great. It arrived with iOS13 with many limitations though. One of those is a proper full-screen modal option. Starting from iOS14, fullScreenCover is supported, but on iOS13 you're out of luck.

To make life a bit easier, I created a small swift package you can use to avoid having to split your client-code API with ugly #available(iOS 14.0, *) flags. The code is available on my personal Github.

It works by stacking an optional view on the top of your view in a ZStack. A FullScreenModalState observable object is injected to the environment, which has two signals you can use:

  • displayContent: you can send an AnyView object which will be presented modally
  • close: you can close your modal by sending an event on this

Integration

Select you main project. On the Swift packages tab, tap on the + icon to add a new dependency. Enter git@github.com:tamasdancsi/ios-full-screen-modal.git, hit next twice and you're ready to go.

Usage

An example project can be found in the Example folder.

  1. Add a fullScreenModalHandling view modifier to your main view.
import SwiftUI
import FullScreenModal

@main
struct MainApp: App {

    var body: some Scene {
        WindowGroup {
            ContentView()
                .fullScreenModalHandling()
        }
    }
}
Enter fullscreen mode Exit fullscreen mode
  1. Display a modal view by sending an AnyView type object through the displayContent signal.
import SwiftUI
import FullScreenModal

struct ContentView: View {

    @Environment(\.fullScreenModalState) var modalState: FullScreenModalState

    var body: some View {
        VStack {
            Button("Display modal") {
                modalState.displayContent.send(
                    ModalContentView().anyView
                )
            }
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(Color.green)
    }
}
Enter fullscreen mode Exit fullscreen mode
  1. Close the presented modal by sending a close signal
struct ModalContentView: View {

    @Environment(\.fullScreenModalState) var modalState: FullScreenModalState

    var body: some View {
        VStack {
            Button("Close modal") {
                modalState.close.send()
            }
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(Color.yellow)
    }
}
Enter fullscreen mode Exit fullscreen mode

Discussion (0)