美文网首页程序员iOS Developer
iOS竖屏App强制某一部分横屏

iOS竖屏App强制某一部分横屏

作者: Fly_Sunshine_J | 来源:发表于2017-08-04 18:08 被阅读427次

前言

很长时间没有更新简书,原因不多说(因为懒),最近比较清闲,想起来写一篇文章来说一下iOS横竖屏轻松切换的过程。 有些需求整体的App只支持竖屏,但是只需要某一部分页面支持横屏,许多的视频类的App都要在竖屏的情况下进行横屏播放,当然还有很多的奇葩需求要横屏来进行实现。

废话少说,进主题

创建项目,App的方向只需要勾选Portrait就行(其实可以不用勾,但是能有几个项目中不勾的呢,我们还是勾上吧)。

勾选方向
前面说可以不勾选因为我们要在AppDelegate中,重写这个方法, 应用程序启动的时候会调用这个方法来给App所需要的屏幕方向:
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
    if([ScreenDirectionManager manager].islandscape) {
        return UIInterfaceOrientationMaskLandscape;
    }else {
        return UIInterfaceOrientationMaskAll;
    }
    
}

其中UIInterfaceOrientationMask是一个NS_OPTIONS, 我们可以随意组合,虽然其中有一些组合好的,但是万一不满足产品的奇葩需求呢,对不对,要提前留一手。

typedef NS_OPTIONS(NSUInteger, UIInterfaceOrientationMask) {
    UIInterfaceOrientationMaskPortrait = (1 << UIInterfaceOrientationPortrait),
    UIInterfaceOrientationMaskLandscapeLeft = (1 << UIInterfaceOrientationLandscapeLeft),
    UIInterfaceOrientationMaskLandscapeRight = (1 << UIInterfaceOrientationLandscapeRight),
    UIInterfaceOrientationMaskPortraitUpsideDown = (1 << UIInterfaceOrientationPortraitUpsideDown),
    UIInterfaceOrientationMaskLandscape = (UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight),
    UIInterfaceOrientationMaskAll = (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskPortraitUpsideDown),
    UIInterfaceOrientationMaskAllButUpsideDown = (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight),
} __TVOS_PROHIBITED;

意思内容不用多解释,应该都能知道什么意思。

其中ScreenDirectionManager这个类控制屏幕是否横屏,是一个单例就一个属性是否需要横屏,比较简单。

@interface ScreenDirectionManager : NSObject

+ (instancetype)manager;

@property (nonatomic, assign, getter=islandscape) BOOL landscape;

@end

如果你的App不包括导航栏(UINaviagtionController)或者(UITabbarController),你只需要重写UIViewController里面的三个方法就行,这三个方法是:

//  返回bool值,决定Controller是否自动旋转
-(BOOL)shouldAutorotate
//返回一个Controller支持的方向
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
//返回现在正在显示的用户界面方向
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation

但是一般的应用至少有个导航栏吧,所以呢你还需要自定义导航栏(UINavigationController),然后在导航栏里面重写这三个方法,如果不重写,就无法达到你想要的效果,感觉就像这个屏幕方向具有传递的性质。但是我感觉UITabbarController的情况应该少数,我这里不讨论这个情况,下次有空再补上,但是我感觉原理应该是一样的,有兴趣的可以自己试一下。

导航栏的屏幕方向和旋转性质要和导航栏最上层的Controller保持一致,所以自定义导航栏重写的三个方法是这样的:

-(BOOL)shouldAutorotate {
    return [[self.viewControllers lastObject] shouldAutorotate];
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}

ViewController中,重写上述的三个方法,返回自己想要的方向,那个改Controller只能是返回的方向,例如:

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationPortrait;
}

- (BOOL)shouldAutorotate {
    return YES;
}

在第二个页面中,也就是跳转的页面中,重写上述的三个方法,返回自己想要的方向,然后在viewWillAppear方法中设定将单例的属性方向改变,然后根据UIDeviceorientation这个属性,根据KVC,强制设置方向,如下;

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [ScreenDirectionManager manager].landscape = YES;
    if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {
//写这句话的目的是保证后面的一句话产生作用,具体不明白为什么,但是不加上会出现bug。有明白的可以告知一下。
        [[UIDevice currentDevice] setValue:@(UIDeviceOrientationUnknown) forKey:@"orientation"];
        [[UIDevice currentDevice] setValue:@(UIDeviceOrientationLandscapeLeft) forKey:@"orientation"];
    }
    
}

还需要在viewWillDisappear中,将单例的横竖屏属性改变回来,因为supportedInterfaceOrientations这个方法会触发AppDelegate中的方向支持方法。

结论

文章描述的不太清楚的,欢迎留言讨论。Demo

相关文章

  • 横竖屏切换 (swift)

    一. 需求 APP中需要支持横屏和竖屏,并在不同的页面 可支持的屏幕旋转方向不一致 整体竖屏,部分强制横屏 整体横...

  • iOS 页面横竖屏

    当App启动的时候需要强制竖屏,进入App后允许横屏或者竖屏的解决办法: 1、修改App-Info.plist文件...

  • Autorotate - 让你的应用支持旋转

    iOS App大多数情况下都是只支持竖屏的,少部分页面才支持旋转,甚至有些页面需要强制横屏。本文将介绍应用如何支持...

  • ios 动画竖屏切换到横屏

    在iOS APP中有个别页面需要从竖屏切换到横屏,网上有很多切屏方法,但最后大多是要调用私有API实现,强制改变设...

  • iOS竖屏App强制某一部分横屏

    前言 很长时间没有更新简书,原因不多说(因为懒),最近比较清闲,想起来写一篇文章来说一下iOS横竖屏轻松切换的过程...

  • 编程技巧汇总

    iOS - 强制某个页面横屏,返回竖屏:https://www.jianshu.com/p/45ca13046ee...

  • 2022-03-05

    iOS16 强制横屏(竖屏)demo CSDN(0资源分)https://download.csdn.net/do...

  • H5页面自动适应横竖屏

    对于样式: 通过html标签可强制移动端浏览器横屏或竖屏但兼容性较差,目前仅有: UC强制竖屏: QQ强制竖屏: ...

  • 0代码解决个别界面横屏问题

    需求 目前iOS功能类app中, 大部分都是只针对竖屏编写的UI, 不过还有少数页面需要加入横屏, 比如横屏阅读文...

  • iOS 强制转屏 强制横屏 强制竖屏

    今天项目中遇到正在看视频的时候账号被挤,如果当时是横屏的情况下,需要强制竖屏。真头疼,网上找了好多方法,终于解决啦...

网友评论

    本文标题:iOS竖屏App强制某一部分横屏

    本文链接:https://www.haomeiwen.com/subject/ruqblxtx.html