iOS开发:屏幕的旋转

Device Orientation:设备方向

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
}

UIInterfaceOrientation:界面方向

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

屏幕旋转的两个通知

// 硬件旋转通知,此时界面还未完成旋转可设置界面的旋转
UIDeviceOrientationDidChangeNotification
// 界面旋转通知,此时界面已经完成旋转
UIApplicationDidChangeStatusBarOrientationNotification

判断当前界面方向

BOOL isPortrait = UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]);
BOOL isLandscape = UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]);

单个页面是否可以旋转

@property(nonatomic, readonly) BOOL shouldAutorotate NS_AVAILABLE_IOS(6_0) __TVOS_PROHIBITED;
@property(nonatomic, readonly) UIInterfaceOrientationMask supportedInterfaceOrientations NS_AVAILABLE_IOS(6_0) __TVOS_PROHIBITED;

  • 面向Orientation的信息:随着屏幕的方向变化

    • [UISCreen bounds]
    • [UISCreen applicationFrame]
    • Status bar frame notifications
    • Keyboard frame notifications
  • 屏幕旋转时使得View有不同布局的实现方法

// way1
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator {
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
    [coordinator animateAlongsideTransition:^(id  _Nonnull context) {
        if (UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation)) {
            _testTextField.frame = CGRectMake(50, 50, 150, 50);
            _testButton.frame = CGRectMake(50, 120, 150, 50);
        } else {
            _testTextField.frame = CGRectMake(50, 50, 150, 50);
            _testButton.frame = CGRectMake(220, 50, 150, 50);
        }
    } completion:^(id  _Nonnull context) {
        
    }];
}
// way2
- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    if (UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation)) {
        _testTextField.frame = CGRectMake(50, 50, 150, 50);
        _testButton.frame = CGRectMake(50, 120, 150, 50);
    } else {
        _testTextField.frame = CGRectMake(50, 50, 150, 50);
        _testButton.frame = CGRectMake(220, 50, 150, 50);
    }
}
  • 旋转屏幕方向
NSNumber *value0 = [NSNumber numberWithInteger:UIDeviceOrientationUnknown];
[[UIDevice currentDevice] setValue:value0 forKey:@"orientation"];
NSNumber *value = [NSNumber numberWithInteger:UIDeviceOrientationLandscapeLeft];
[[UIDevice currentDevice] setValue:value forKey:@"orientation"];

  • 需求:APP总体不跟随设备的旋转来改变界面的方向,个别页面横屏展示

实现思路:首先APP应该支持横屏和竖屏的展示,也就是说在TARGETS中的Device Orientation选项勾选横屏和竖屏选项。假设ViewController是根视图,那么当ViewController的- (BOOL)shouldAutorotate方法返回为YES的时候,界面的方向跟随设备方向变化。在NV结构(NavigationController上放置ViewController的结构)中需横屏展示的ViewController可不是根视图,此时界面是否跟随设备旋转取决于根视图NavigationController的- (BOOL)shouldAutorotate方法的返回值。在这种情况中,可重写NavigationController的- (BOOL)shouldAutorotate方法返回Navigation栈中的顶部ViewController的shouldAutorotate,以此达到在单个页面随时控制其横屏的效果。横屏通过Key-Value的方法修改设备方向来达到目的。

一、勾选横屏和竖屏选项

iOS开发:屏幕的旋转_第1张图片
勾选横屏和竖屏选项

二、重写- (BOOL)shouldAutorotate返回栈顶控制器的shouldAutorotate

@interface MyNav : UINavigationController

@end

@implementation MyNav

- (BOOL)shouldAutorotate {
    return self.topViewController.shouldAutorotate;
}

@end

三、在将要横屏显示的ViewController中,重写- (BOOL)shouldAutorotate,重点是用全局变量控制它的返回值

@interface LandscapeViewController () {
    BOOL _allowAutorotate;
}

- (BOOL)shouldAutorotate {
    [super shouldAutorotate];
    return _allowAutorotate;
}

四、通过Key-Value改变设备方向

_allowAutorotate = YES;
NSNumber *value0 = [NSNumber numberWithInteger:UIDeviceOrientationUnknown];
[[UIDevice currentDevice] setValue:value0 forKey:@"orientation"];
NSNumber *value = [NSNumber numberWithInteger:UIDeviceOrientationLandscapeLeft];
[[UIDevice currentDevice] setValue:value forKey:@"orientation"];
_allowAutorotate = NO;

你可能感兴趣的:(iOS开发:屏幕的旋转)