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的方法修改设备方向来达到目的。
一、勾选横屏和竖屏选项
二、重写- (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;