强制iOS视图不旋转,同时仍允许子项旋转

强制iOS视图不旋转,同时仍允许子项旋转,第1张

概述我有一个带有子视图控制器的视图控制器. tab bar controller||nav controller||UIPageViewController (should rotate)||A (Video Player) (shouldn't rotate)||B (Controls overlay) (should rotate) 应该强制A始终保持纵向,但应允许B自由旋 @H_404_1@我有一个带有子视图控制器的视图控制器.
tab bar controller||nav controller||UIPageVIEwController (should rotate)||A (VIDeo Player) (shouldn't rotate)||B (Controls overlay) (should rotate)

应该强制A始终保持纵向,但应允许B自由旋转.

我知道shouldautorotate适用于任何视图控制器及其子级,但有什么方法可以解决这个问题吗?似乎我可以使用shouldautorotatetoInterfaceOrIEntation,但这在iOS 8中被阻止.

我想让视频播放器保持静态(因此无论设备方向如何,水平视频总是水平的),而控制层子视图覆盖允许自由旋转.

我正在使用Swift.

解决方法 我有这个确切的问题,很快发现有很多关于自动旋转的不好的建议,特别是因为iOS 8处理它与以前的版本不同.

首先,您不希望手动应用反向旋转或订阅UIDevice方向更改.执行反旋转仍会导致难看的动画,并且设备方向并不总是与界面方向相同.理想情况下,您希望相机预览保持真正冻结状态,并使您的应用UI与状态栏方向和尺寸相匹配,就像本机相机应用程序一样.

在iOS 8中进行方向更改期间,窗口本身会旋转而不是它包含的视图.您可以将多个视图控制器的视图添加到单个UIWindow,但只有rootVIEwController才有机会通过shouldautorotate()进行响应.即使您在视图控制器级别进行旋转决策,它也是实际旋转的父窗口,从而旋转其所有子视图(包括来自其他视图控制器的子视图).

解决方案是两个UIWindow堆叠在一起,每个都旋转(或不旋转)具有自己的根视图控制器.大多数应用程序只有一个,但没有理由你不能有两个,并像任何其他UIVIEw子类一样覆盖它们.

这是一个工作概念验证,which I’ve also put on GitHub here.你的特殊情况稍微复杂一点,因为你有一堆包含视图控制器,但基本的想法是一样的.我将在下面谈谈一些具体问题.

@UIApplicationMainclass AppDelegate: UIResponder,UIApplicationDelegate {    var cameraWindow: UIWindow!    var interfaceWindow: UIWindow!    func application(application: UIApplication,dIDFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool {        let screenBounds = UIScreen.mainScreen().bounds        let inset: CGfloat = fabs(screenBounds.wIDth - screenBounds.height)        cameraWindow = UIWindow(frame: screenBounds)        cameraWindow.rootVIEwController = CameraviewController()        cameraWindow.backgroundcolor = UIcolor.blackcolor()        cameraWindow.hIDden = false        interfaceWindow = UIWindow(frame: CGRectInset(screenBounds,-inset,-inset))        interfaceWindow.rootVIEwController = InterfaceVIEwController()        interfaceWindow.backgroundcolor = UIcolor.clearcolor()        interfaceWindow.opaque = false        interfaceWindow.makeKeyAndVisible()        return true    }}

在interfaceWindow上设置负插入使其略大于屏幕边界,有效地隐藏了您看不到的黑色矩形蒙版.通常您不会注意到因为蒙版随窗口一起旋转,但由于相机窗口是固定的,因此在旋转过程中,蒙版在角落中变得可见.

class CameraviewController: UIVIEwController {    overrIDe func shouldautorotate() -> Bool {        return false    }}

正是您所期望的,只需为AVCapturePrevIEwLayer添加您自己的设置.

class InterfaceVIEwController: UIVIEwController {    var contentVIEw: UIVIEw!    overrIDe func vIEwDIDLoad() {        super.vIEwDIDLoad()        contentVIEw = UIVIEw(frame: CGRectZero)        contentVIEw.backgroundcolor = UIcolor.clearcolor()        contentVIEw.opaque = false        vIEw.backgroundcolor = UIcolor.clearcolor()        vIEw.opaque = false        vIEw.addSubvIEw(contentVIEw)    }    overrIDe func vIEwWillLayoutSubvIEws() {        super.vIEwWillLayoutSubvIEws()        let screenBounds = UIScreen.mainScreen().bounds        let offset: CGfloat = fabs(screenBounds.wIDth - screenBounds.height)        vIEw.frame = CGRectOffset(vIEw.bounds,offset,offset)        contentVIEw.frame = vIEw.bounds    }    overrIDe func supportedInterfaceOrIEntations() -> Int {        return Int(UIInterfaceOrIEntationMask.All.rawValue)    }    overrIDe func shouldautorotate() -> Bool {        return true    }}

最后一个技巧是撤消我们应用于窗口的负插入,我们通过偏移视图相同的量并将contentVIEw视为主视图来实现.

对于你的应用程序,interfaceWindow.rootVIEwController将是你的标签栏控制器,它又包含一个导航控制器等.当你的摄像机控制器出现时,所有这些视图都必须是透明的,这样摄像机窗口就可以显示在它下面.出于性能原因,您可能会考虑将它们保持不透明状态,并且仅在实际使用相机时将所有内容设置为透明,并将相机窗口设置为隐藏(如果不是(同时也关闭捕获会话)).

抱歉发布一本小说;我还没有在其他任何地方看到这个问题,我花了一段时间才弄明白,希望它可以帮助你和其他任何试图获得相同行为的人.即使Apple的AVCam示例应用程序也不能正确处理它.

The example repo I posted还包括已设置相机的版本.祝好运!

总结

以上是内存溢出为你收集整理的强制iOS视图不旋转,同时仍允许子项旋转全部内容,希望文章能够帮你解决强制iOS视图不旋转,同时仍允许子项旋转所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1101397.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-28
下一篇 2022-05-28

发表评论

登录后才能评论

评论列表(0条)

保存