iosswiftuiswipehomescreen

preferredScreenEdgesDeferringSystemGestures in SwiftUI


in UIKit there is an option to disable "Home" system swipe up from bottom (not completely disable, but swipe ignores first time and will force user to repeat it if he really wants it). setNeedsUpdateOfScreenEdgesDeferringSystemGestures() actually does right what I need.

But how do I reach the same in SwiftUI?

I tried to call this method in SceneDelegate like this:

        let window = UIWindow(windowScene: windowScene)
        let uiKitView = UIHostingController(rootView: contentView)
        uiKitView.setNeedsUpdateOfScreenEdgesDeferringSystemGestures()
        window.rootViewController = uiKitView

but its doesn't work if you doesn't override preferredScreenEdgesDeferringSystemGesturesto return .all I can't override this computed property of UIHostingController:

extension UIHostingController {
    open override var preferredScreenEdgesDeferringSystemGestures: UIRectEdge{
        return [.all];
    }
}

I gets warning:

Extensions of generic classes cannot contain '@objc' members

Anybody knows how to reach that?


Solution

  • Update Xcode 14 / iOS 16

    Now SwiftUI supports it naturally with defersSystemGestures modifier:

      body: some View {
        MainView()
          .defersSystemGestures(on: .bottom)   // << here !!
      }
    

    Original

    Just override it in custom hosting controllers

    class MyHostingController<Content: View>: UIHostingController<Content> {
        open override var preferredScreenEdgesDeferringSystemGestures: UIRectEdge{
            return [.all];
        }
    }
    

    and use it as root controller

    let window = UIWindow(windowScene: windowScene)
    
    let controller = MyHostingController(rootView: contentView)
    controller.setNeedsUpdateOfScreenEdgesDeferringSystemGestures()
    
    window.rootViewController = controller