How to lock screen orientation for a specific view?

I have one view, that need to be locked in portrait only on the iPhone, but not on the iPad, but while it seems to be kinda easy on UIKit, I cannot find any solution for the SwiftUI. For UIKit it works through overriding supportedInterfaceOrientations in the controller, but I don't see any easy way to do so in the SwiftUI

Replies

Oooh, I know this one! There's a discussion here: SwiftUI: Force orientation on a per screen basis.


I also implemented this as part of my open-source toolkit: https://github.com/AlanQuatermain/AQUI/blob/master/Sources/AQUI/OrientationLock.swift


The version on Github allows views to specify their individual constraints, and will collapse them all into a single allowable state. If one view says 'all but upside down' and another says 'portrait only' then the effective value will be 'portrait only'.

struct NetflixApp: App {

  @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

}

class AppDelegate: NSObject {



  // 屏幕旋转锁定



  static var orientationLock = UIInterfaceOrientationMask.portrait

}

extension AppDelegate: UIApplicationDelegate {

  func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {

    return AppDelegate.orientationLock

  }

}

SomeView
.onDisappear(perform: {

      DispatchQueue.main.async {

        AppDelegate.orientationLock = UIInterfaceOrientationMask.portrait

        UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")

        UINavigationController.attemptRotationToDeviceOrientation()

      }

    })

    .onAppear(perform: {

      AppDelegate.orientationLock = UIInterfaceOrientationMask.landscape

      UIDevice.current.setValue(UIInterfaceOrientation.landscapeLeft.rawValue, forKey: "orientation")

      UINavigationController.attemptRotationToDeviceOrientation()

    })