https://www.jianshu.com/p/d1d61a5350d5
UIDeviceOrientation 是机器硬件的当前旋转方向 这个你只能取值 不能设置
UIInterfaceOrientation 是你程序界面的当前旋转方向 这个可以设置
设定手机的屏幕旋转:首先要把手机本身的屏幕锁定按钮打开;出现提示“竖排方向锁定:关闭”,即代表屏幕锁定关闭,横放手机时屏幕会自动旋转。
===========系统支持屏幕旋转:
默认读取plist里面设置的方向(优先级最高)等同于Xcode Geneal设置里面勾选
application window设置的级别次之
然后是UINavigationcontroller
级别最低的是viewcontroller
-(UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
return UIInterfaceOrientationMaskPortrait|UIInterfaceOrientationMaskLandscapeLeft|UIInterfaceOrientationMaskLandscapeRight;
}
1.//将要旋转到某个方向的时候调用此方法(iOS8之前)
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
//Landscape : 横屏 Portrait: 竖屏
// 传入一个方向值, 如果是横屏, 则返回YES
if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation)) {
NSLog(@"横屏");
}
// 传入一个方向值, 如果是竖屏, 则返回YES
if (UIInterfaceOrientationIsPortrait(toInterfaceOrientation)) {
NSLog(@"竖屏");
}
}
2.#pragma mark iOS8以后的方法
ViewController的View的size被他的Parent Controller改变时,会触发这个方法。(比如rootViewController在它的window旋转的时候)。我们在重写这个方法时,确保要调用super,来保证size改变的这条消息能够正常传递给它的Views或者ChildViewControllers。
// 如果实现了iOS8以后的方法, 则旧版方法会覆盖
//视图发生了大小改变的时候会调用此方法 大小改变 == 横竖切换
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
NSLog(@"size; %@", NSStringFromCGSize(size));
// 建议如果背景色不一致的情况下, 做动画同步的处理, 否则视觉上很不舒服
//动画同步 --> 系统默认0.25 而选择是0.4
[UIView animateWithDuration:[coordinator transitionDuration] animations:^{
//方法一:
if (size.width == HMScreenMaxWidth1024) {
NSLog(@"横屏");
self.dockView.width = HMDockMaxWidth;
self.dockView.height = HMScreenMinWidth768;
} else {
NSLog(@"竖屏");
self.dockView.width = HMDockMinWidth;
self.dockView.height = HMScreenMaxWidth1024;
}
}];
//方法二
// if (size.width > size.height) {
// NSLog(@"横屏");
// }
//方法三 orientation: 方向
// if ([UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeLeft || [UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeRight) {
// NSLog(@"横屏");
// }
}
3.============注意下面的方法必须在最顶层的控制器中才能生效,单独在子控制器中使用没有效果;例如在navigation控制器中的更控制其中使用没有效果,在tabbarVC的子控制器中也没有效果;如果是在有多层控制器的控制器中任一层级的控制器push出来的控制器也没有效果,如果是present出来的,在模态出来的控制器中设置是有效果的;
iOS6.0以后:UINavigationcontroller和viewcontroller中的屏幕旋转的方法
//是否支持旋转屏幕
- (BOOL)shouldAutorotate
{
return YES;//如果是NO,这个控制器不能旋转
}
//支持哪些方向
- (UIInterfaceOrientationMask)supportedInterfaceOrientations{
//这里的返回值必须是appdelegate中返回的方向中有的,或infoplist中有的,或者target中设置的
return UIInterfaceOrientationMaskPortrait;//可以同时返回多个方向;
}
上面的两个方法也可以被直接调用,用来控制不同页面的旋转:
-(BOOL)shouldAutorotate{
return [self.topViewController shouldAutorotate];//在navigation控制器中调用vc的旋转方法;
}
//支持的方向
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return [self.topViewController supportedInterfaceOrientations];//在navigation控制器中调用vc的旋转方法;
}
//默认显示的方向
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
//这里是显示控制器第一次启动时默认显示的方向,这里的返回值必须是上面的 -(UIInterfaceOrientationMask)supportedInterfaceOrientations{return}返回值中的一个。否则不生效。
return UIInterfaceOrientationPortrait;
}
4.===========AppDelegate下面的屏幕旋转方法----从iOS6.0 开始
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
returnUIInterfaceOrientationMaskAll;//可以返回多个方向,用 | 隔开
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
//宣告一个UIDevice指标,取得目前Device的信息;
UIDevice *device = [UIDevicecurrentDevice] ;
//取得当前Device的方向,敘述。(Device的方向型能为Integer)
switch (device.orientation) {
caseUIDeviceOrientationFaceUp:
NSLog(@"屏幕朝上平躺");
break;
caseUIDeviceOrientationFaceDown:
NSLog(@"屏幕朝下平躺");
break;
//系统无法判断目前Device的方向,有可能是斜置
caseUIDeviceOrientationUnknown:
NSLog(@"未知方向");
break;
caseUIDeviceOrientationLandscapeLeft:
NSLog(@"屏幕幕向左橫置");
break;
caseUIDeviceOrientationLandscapeRight:
NSLog(@"屏幕向右橫置");
break;
caseUIDeviceOrientationPortrait:
NSLog(@"屏幕直立");
break;
caseUIDeviceOrientationPortraitUpsideDown:
NSLog(@"屏幕直立,上下顛倒");
break;
default:
NSLog(@"无法识别");
break;
}
// Return YES for supported orientations
return (interfaceOrientation ==UIInterfaceOrientationLandscapeLeft);//只支持向左横向,YES表示支持所有方向
}
//1.注册UIApplicationDidChangeStatusBarOrientationNotification通知(举例:在一个viewcontroller类的viewdidload中注册该通知),示例代码如下:
-(void)noti{
[[NSNotificationCenterdefaultCenter]addObserver:selfselector:@selector(statusBarOrientationChange:)name:UIApplicationDidChangeStatusBarOrientationNotificationobject:nil];
}
- (void)statusBarOrientationChange:(NSNotification *)notification{
UIInterfaceOrientation orientation = [[UIApplicationsharedApplication]statusBarOrientation];
if (orientation ==UIInterfaceOrientationLandscapeRight)// home键靠右
{
//
}
if (orientation ==UIInterfaceOrientationLandscapeLeft)// home键靠左
{
}
if (orientation ==UIInterfaceOrientationPortrait){
}
if (orientation ==UIInterfaceOrientationPortraitUpsideDown){
}
}
//注意这种方式监听的是StatusBar也就是状态栏的方向,所以这个是跟你的布局有关的,你的布局转了,才会接到这个通知,而不是设备旋转的通知。当我们关注的东西和布局相关而不是纯粹设备旋转,我们使用上面的代码作为实现方案比较适合。
//2.注册UIDeviceOrientationDidChangeNotification通知
(举例:我们同样在一个viewcontroller类的viewdidload中注册该通知),示例代码如下:
-(void)monitorDevice{
[[NSNotificationCenterdefaultCenter]addObserver:self selector:@selector(orientChange:)
name:UIDeviceOrientationDidChangeNotificationobject:nil];
}
- (void)orientChange:(NSNotification *)noti
{
NSDictionary* ntfDict = [notiuserInfo];
UIDeviceOrientation orient = [UIDevicecurrentDevice].orientation;
/*
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 */
switch (orient)
{
caseUIDeviceOrientationPortrait:
break;
caseUIDeviceOrientationLandscapeLeft:
break;
caseUIDeviceOrientationPortraitUpsideDown:
break;
caseUIDeviceOrientationLandscapeRight:
break;
default:
break;
}
}
//注意到这种方式里面的方向还包括朝上或者朝下,很容易看出这个完全是
根据设备自身的物理方向得来的,当我们关注的只是物理朝向时,我们通常需要注册该通知来解决问题。