繁体   English   中英

在没有 .faceUp 和 .faceDown 的情况下对方向变化做出反应

[英]Reacting to orientation changes without .faceUp and .faceDown

我有一个UIView ,当设备处于纵向/横向模式时,它会随着动画出现/消失。

我这样做:

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
        }
    }

问题是.faceDown.faceUp 我想忽略这些方向的方向变化并且没有任何变化。 将它们置于default:当设备放回纵向时, switch导致不必要的重复动画。

我相信我可以一起破解一个解决方案。 但我发现问题的简单性令人沮丧。

是否有一个属性只通知.portrait.landscapeRight.landscapeLeft.portraitUpsideDown

是,不赞成使用interfaceOrientation ,现在应该使用statusBarOrientation或traits和相关方法来检测当前方向或方向变化。
我想向您指出这篇文章 ,设备方向不会考虑用户可以在选项中设置的最终方向锁定。
虽然statusBarOrientation似乎被弃用显然只是作为规定的制定者在这里从苹果公司的员工。

您如何在人像应用程序中呈现风景视图控制器? 这只是可能的示例之一:

// ApplicationDelegate overridden method
    func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
        if topController() is FullGraphViewController {
            return .all
        }  else {
            return .portrait
        }
    }

基本上,我说的是当呈现FullGraphViewController时,它可以所有可能的方向显示。

// 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
    }

在这里我是说视图应该以纵向显示,这将导致一个很好的定向动画,该视图可以旋转,并且如果激活了风景标志,它可以在所有方向上旋转,除了上下颠倒。
要拦截方向更改,您可以:

  • 使用设备方向更改,但仅用于触发景观视图控制器的显示
  • 使用特征变化回调来触发演示,但是您的应用程序类似于我的应用,并且您在常规设置中仅选择纵向定位,因此不会收到任何这些调用回调

在要显示横向界面的vc中的方向更改回调中,可以显示横向视图控制器:

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
        }
    }
}

landActivelandActive的一个属性,设置该属性时将要求从端口到风景的旋转开始。

var landActive = true {
        didSet(old) {
            UIViewController.attemptRotationToDeviceOrientation()
            view.setNeedsLayout()
            view.layoutIfNeeded()
        }
    }


请注意函数UIDeviceOrientationIsValidInterfaceOrientation ,它非常重要,并且使面朝上和面朝下。

使用self.view.window?.windowScene?.interfaceOrientation

该值将是portraitportraitUpsideDownlandscapeRightlandscapeLeft

有关文档,请参见此处

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM