iOS 开发单个页面横屏处理(swift 版)

问题

iOS开发中大部分情况都是只允许竖屏的,但是偶尔几个页面需要做横屏处理(或者只能横屏)

解决方案

Applegate.swift文件中的修改

首先在AppDelegate中新增属性

    var isLandscape = false

然后给AppDelegate新增扩展


// MARK: - 是否横屏
extension AppDelegate {
    @objc(application:supportedInterfaceOrientationsForWindow:) func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
        if isLandscape {
            //return .landscapeRight //只允许全景模式(横屏)
            return .all //允许所有模式,手机转动会跟随转动
        }else{
            return .portrait //只能竖屏
        }
    }
}

/***
 解决iOS 9 横竖屏的问题
 This is a bug in iOS 9 that it failed to retrieve the supportedInterfaceOrientations for UIAlertController. And it seems it dropped to an infinite recursion loop in looking for the supportedInterfaceOrientations for UIAlertController
 https://stackoverflow.com/questions/31406820/uialertcontrollersupportedinterfaceorientations-was-invoked-recursively
 */
extension UIAlertController {
    open override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return UIInterfaceOrientationMask.portrait
    }
    open override var shouldAutorotate: Bool {
        return false
    }
}

info.plist 添加

    <key>UIViewControllerBasedStatusBarAppearance</key>
    <true/>

设置好了后,接下来处理需要横屏幕的页面

需要横屏的页面BTKLineVC

// MARK: - 横屏处理
extension BTKLineVC {
    //运行页面随设备转动
    override var shouldAutorotate : Bool {
        return true
    }

    override func viewWillAppear(_ animated: Bool) {
        if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
            //允许横屏
            appDelegate.isLandscape = true

            // 强制横屏打开下面两行代码即可
            //let value = UIInterfaceOrientation.landscapeRight.rawValue
            //UIDevice.current.setValue(value, forKey: "orientation")

        }
        super.viewWillAppear(animated)
    }

    override func viewWillDisappear(_ animated: Bool) {
        navigationController?.setNavigationBarHidden(false, animated: false)

        if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
            //禁止横屏
            appDelegate.isLandscape = false
        }
        //强制为竖屏
        let value = UIInterfaceOrientation.portrait.rawValue
        UIDevice.current.setValue(value, forKey: "orientation")
        super.viewWillDisappear(animated)
    }

        //下面方法是处理navgation相关的逻辑,如果控制器没有nav,省略
    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        coordinator.animate(alongsideTransition: { [weak self] (context) in
            let orient = UIApplication.shared.statusBarOrientation
            switch orient {
            case .landscapeLeft, .landscapeRight:
                //横屏时禁止左拽滑出
                self?.navigationController?.interactivePopGestureRecognizer?.isEnabled = false
                self?.navigationController?.setNavigationBarHidden(true, animated: false)
            default:
                //竖屏时允许左拽滑出
                self?.navigationController?.interactivePopGestureRecognizer?.isEnabled = true
                self?.navigationController?.setNavigationBarHidden(false, animated: false)
            }
        })
        super.viewWillTransition(to: size, with: coordinator)
    }
}

8月3号 补充

上面处理横屏会引起一个bug,就是如果手机横屏进入(与设置方向相同),布局可能会错乱。
原因是:这里布局我是按照横屏处理的,以上处理横屏方式适用于页面跟随系统,即页面可以横屏也可以竖屏

bug解决办法

  1. 设置系统只能竖屏
    image.png

  2. 需要横屏的页面取消方向跟随系统,只允许横屏

    // MARK: - 横屏处理
    extension BTKLineVC {
    //运行页面随设备转动
    override open var shouldAutorotate: Bool {
        return false
    }
    //支持的方向: 右边
    override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return .landscapeRight
    }
    // 优先展示的方向: 右边
    override open var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
        return .landscapeRight
    }
    }

11月25号更新

在iOS13时,对于 present 的页面,需要设置取消弹框新模式 添加以下代码在viewDidLoad中即可:
modalPresentationStyle = UIModalPresentationStyle.fullScreen

备注

本文swift版本用的是swift4,如果代码异常根据版本稍作修改即可食用, 用OC的同学可以根据代码自行翻译,早用swift,脱离OC苦海。

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 1

我有流量,寻求个人游戏开发者合作,有意者联系微信:15322714231

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!