I have a UIView
that appears/disappears with an animation when the device is in portrait/landscape mode.
I am doing it like this:
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(deviceOrientationChanged), name: Notification.Name.UIDeviceOrientationDidChange, object: nil)
}
func deviceOrientationChanged() {
switch UIDevice.current.orientation {
case .portrait:
//appear
case .landscapeLeft, .landscapeRight:
//disappear
case default:
//appear; here lies the problem
}
}
The issue are .faceDown
and .faceUp
. I want to ignore the orientation changes to these orientation and have nothing change. Putting them in the default:
of the switch
results in uneccessarily repeated animations when the device is put back into portrait.
I am sure I could hack together a solution. But I find the simplicity of the problem frustrating.
Is there a property that only informs about changes to .portrait
, .landscapeRight
, .landscapeLeft
and .portraitUpsideDown
?
Yes interfaceOrientation
has been deprecated, now you should use statusBarOrientation
or traits and related methods to detect the current orientation or the changes in orientation.
I'd like to point you to this post , device orientation will not consider the eventual orientation lock that the user can set in the options.
While statusBarOrientation
seems to be deprecated is apparently only on the setter as stated here from an Apple employee.
How could you present a landscape view controller in a portrait application? this is just one of the possible example:
// ApplicationDelegate overridden method
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
if topController() is FullGraphViewController {
return .all
} else {
return .portrait
}
}
Basically I say that when a FullGraphViewController is presented it can be displayed in all possible orientations.
// FullgraphViewController overridden methods
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
if landActive {
return [UIInterfaceOrientationMask.allButUpsideDown]
}
return [UIInterfaceOrientationMask.portrait]
}
override var shouldAutorotate: Bool {
return true
}
override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
return .portrait
}
Here I'm saying that view should be presented in portrait this will lead to a nice orientation animation, the view can rotate and if landscape flag is active it can rotate in all orientation except upside-down.
To intercept orientation changes you can:
Inside the orientation changes callback from the vc where you want to present the landscape interface, you can present your landscape view controller:
func orientationChanged(_ notification: Notification) {
let orientation = UIDevice.current.orientation
if UIDeviceOrientationIsValidInterfaceOrientation(orientation) && UIDeviceOrientationIsLandscape(orientation) {
let vc = storyboard!.instantiateViewController(withIdentifier: Constants.ViewControllerIdentifiers.LandscapeFullGraphViewController) as! FullGraphViewController
vc.title = navigatorViewController?.navigationBarView.barTitle
vc.instrumentInfo = instrumentInfo
vc.modalTransitionStyle = .crossDissolve
present(vc, animated: true) {
vc.landActive = true
}
}
}
The landActive
is a property of the FullGraphViewController that when is set asks the rotation from port to landscape to begin.
var landActive = true {
didSet(old) {
UIViewController.attemptRotationToDeviceOrientation()
view.setNeedsLayout()
view.layoutIfNeeded()
}
}
Please note the function UIDeviceOrientationIsValidInterfaceOrientation , that is very important and discharges faceup and facedown.
Use self.view.window?.windowScene?.interfaceOrientation
.
This value will be either portrait
, portraitUpsideDown
, landscapeRight
, or landscapeLeft
.
See here for documentation.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.