iOS_控制屏幕旋转

1 首先在Xcode工程配置中设置 项目支持哪些方向上的旋转

从上往下分别是  上、下、左右  如图所示 表示当前项目 支持竖屏、左右横屏。Xcode中的配置是全局的,意味着项目中所有的控制器都默认支持这些方向的旋转。

2 控制器单独控制 

Xcode工程配置中设置了全局支持的旋转方向,不过实际项目中经常不是所有的控制器都支持一样的旋转方向,所以需要通过代码实现控制器的单独配置。

为了能看懂代码 这里先介绍下跟旋转有关的三个枚举   

UIDeviceOrientation: 设备旋转方向


typedef NS_ENUM(NSInteger, UIDeviceOrientation) {
    UIDeviceOrientationUnknown,
    UIDeviceOrientationPortrait,            // Device oriented vertically, home button on the bottom
    UIDeviceOrientationPortraitUpsideDown,  // Device oriented vertically, home button on the top
    UIDeviceOrientationLandscapeLeft,       // Device oriented horizontally, home button on the right
    UIDeviceOrientationLandscapeRight,      // Device oriented horizontally, home button on the left
    UIDeviceOrientationFaceUp,              // Device oriented flat, face up
    UIDeviceOrientationFaceDown             // Device oriented flat, face down
} API_UNAVAILABLE(tvos);


UIInterfaceOrientation:屏幕旋转方向

typedef NS_ENUM(NSInteger, UIInterfaceOrientation) {
    UIInterfaceOrientationUnknown            = UIDeviceOrientationUnknown,
    UIInterfaceOrientationPortrait           = UIDeviceOrientationPortrait,
    UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,
    UIInterfaceOrientationLandscapeLeft      = UIDeviceOrientationLandscapeRight,
    UIInterfaceOrientationLandscapeRight     = UIDeviceOrientationLandscapeLeft
} API_UNAVAILABLE(tvos);


UIInterfaceOrientationMask:看代码的定义 可以理解为 用于对UIInterfaceOrientation的描述


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),
} API_UNAVAILABLE(tvos);



然后通过查看官方API可以看到UIViewController中声明了以下三个属性


    // 是否支持屏幕旋转  当这个值为NO时  当前控制器只能竖屏
    @property(nonatomic, readonly) BOOL shouldAutorotate ;
    
    // 当前控制器支持的旋转方向
    @property(nonatomic, readonly) UIInterfaceOrientationMask supportedInterfaceOrientations;
    
    // 页面出现时的默认旋转方向
    @property(nonatomic, readonly) UIInterfaceOrientation preferredInterfaceOrientationForPresentation;

这三个属性是只读的,所以没法用set方法去设置,不过可以通过重写get方法的形势来返回想要的值  比如以下代码所示


// 返回yes表示支持旋转
- (BOOL)shouldAutorotate
{
    return YES;
}


// 支持竖屏和横屏
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscape);
}


// 默认旋转左边
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return UIInterfaceOrientationLandscapeLeft;
}

不过要注意的是  如果当前控制器是属于一个导航控制器的 那么导航控制器中要实现

// 是否支持自动转屏
- (BOOL)shouldAutorotate {
    return self.topViewController.shouldAutorotate;
}

// 支持哪些屏幕方向
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return self.topViewController.supportedInterfaceOrientations;
}

// 默认的屏幕方向(当前ViewController必须是通过模态出来的UIViewController(模态带导航的无效)方式展现出来的,才会调用这个方法)
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return self.topViewController.preferredInterfaceOrientationForPresentation;
}

同样的 如果控制器外面还有一层TabBarViewControllre那么 TabBarViewControllre要实现

// 是否支持自动转屏
- (BOOL)shouldAutorotate {
    return self.selectedViewController.shouldAutorotate;
}

// 支持哪些屏幕方向
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return self.selectedViewController.supportedInterfaceOrientations;
}

// 默认的屏幕方向(当前ViewController必须是通过模态出来的UIViewController(模态带导航的无效)方式展现出来的,才会调用这个方法)
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return self.selectedViewController.preferredInterfaceOrientationForPresentation;
}

到了这里 我们就知道了 怎么全局或单独配置某个ViewController是否支持、支持哪些方向的旋转。当手机设备旋转时,界面也会相应的旋转。

3 监听屏幕的旋转

既然某个VC支持了屏幕旋转,也就意味着 该界面的竖屏和横屏是两套不同的UI,所以当屏幕旋转时,监听系统发出的通知,及时刷新UI 做好横竖屏的适配。


        // 监听屏幕旋转
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationDidChange) name:UIDeviceOrientationDidChangeNotification object:nil];
        

- (void)orientationDidChange
{
    switch ([UIDevice currentDevice].orientation) {
        case UIDeviceOrientationPortrait:
            self.isFullScreen = NO;
            break;
        case UIDeviceOrientationLandscapeLeft:
            self.isFullScreen = YES;
            break;
        case UIDeviceOrientationLandscapeRight:
            self.isFullScreen = YES;
            break;
        default:
            break;
    }
}

4 主动控制屏幕的旋转

当锁定了iPhone的方向之后,旋转手机,UIDevice的orientation属性不会改变,同时系统也不会发出UIDeviceOrientationDidChangeNotification通知,此时我们只能通过代码的方式强制修改当前Device的orientation,当orientation改变时,系统会发出UIDeviceOrientationDidChangeNotification通知


//  因为orientation属性是只读的  所有这里通过KVC的形式来设置值  
    [[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:orientation]
                                       forKey:@"orientation"];

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值