iOS手动控制界面旋转
2014-06-04 19:51
597 查看
条条大道通罗马,解决同一个问题的手段也是多种多样的。对于《iOS 6及以上控制个别视图旋转案例》中提到的案例,我们是利用系统自带的旋转机制来解决问题的。同样地,我们也可以自己coding解决问题,且最终效果同系统的旋转动画效果是一模一样的。废话不多说,下面来大概讲解一下。
手动控制界面旋转的核心思路就是利用UIView的transform属性,旋转App的根视图。何为根视图?如果你的App的window.rootViewController是UINavigationController,那么根视图就是navigationController.view。为了旋转的效果和系统的一致,我们还需要为它添加一个UIView动画。
接着我们来具体操作一下,首先,建立一个测试工程,工程结构如下图。测试工程的根视图控制器是一个UINavigationController,在这个UINavigationController的栈中有视图控制器a(FirstViewController的一个实例)和控制器b(SecondViewController的一个实例),控制器b通过在控制器a中点击按钮push进入。
在SecondViewController.h文件中添加代码,如下
为什么要添加UINavigationController类别?因为旋转的时候我们需要同时去旋转statusBar(状态栏),要旋转statusBar必须在shouldAutorotate方法中返回NO。
运行测试项目并旋转设备,能看到我们已经成功手动控制界面旋转,且旋转的动画效果与系统默认的旋转效果是一模一样的。和之前那篇文章中提到的解决方法相比,有了更高的自由度,开发者能够随性控制界面的旋转。
测试工程:下载
手动控制界面旋转的核心思路就是利用UIView的transform属性,旋转App的根视图。何为根视图?如果你的App的window.rootViewController是UINavigationController,那么根视图就是navigationController.view。为了旋转的效果和系统的一致,我们还需要为它添加一个UIView动画。
接着我们来具体操作一下,首先,建立一个测试工程,工程结构如下图。测试工程的根视图控制器是一个UINavigationController,在这个UINavigationController的栈中有视图控制器a(FirstViewController的一个实例)和控制器b(SecondViewController的一个实例),控制器b通过在控制器a中点击按钮push进入。
在SecondViewController.h文件中添加代码,如下
#import <UIKit/UIKit.h> @interface SecondViewController : UIViewController @property (nonatomic,assign) BOOL isLandscape; - (IBAction)rotateBtnClicked:(id)sender; @end在SecondViewController.m文件中添加代码,如下
#import "SecondViewController.h" @implementation SecondViewController #pragma mark - view life cycle - (void)viewDidLoad { [super viewDidLoad]; self.title = @"Second"; self.isLandscape = NO; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeFrames:) name:UIDeviceOrientationDidChangeNotification object:nil]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } #pragma mark - methods - (void)rotateToLandscapeLeft { NSTimeInterval duration = [[UIApplication sharedApplication] statusBarOrientationAnimationDuration]; [UIView animateWithDuration:duration animations:^{ [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft]; self.navigationController.view.transform = CGAffineTransformMakeRotation(- M_PI/2); self.navigationController.view.bounds = CGRectMake(0, 0, [self screenHeight], 320); } completion:^(BOOL finished) { self.isLandscape = YES; }]; } - (void)rotateToLandscapeRight { NSTimeInterval duration = [[UIApplication sharedApplication] statusBarOrientationAnimationDuration]; [UIView animateWithDuration:duration animations:^{ [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight]; self.navigationController.view.transform = CGAffineTransformMakeRotation(M_PI/2); self.navigationController.view.bounds = CGRectMake(0, 0, [self screenHeight], 320); } completion:^(BOOL finished) { self.isLandscape = YES; }]; } - (void)rotateToPortrait { NSTimeInterval duration = [[UIApplication sharedApplication] statusBarOrientationAnimationDuration]; [UIView animateWithDuration:duration animations:^{ [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait]; self.navigationController.view.transform = CGAffineTransformMakeRotation(0); self.navigationController.view.bounds = CGRectMake(0, 0, 320, [self screenHeight]); } completion:^(BOOL finished) { self.isLandscape = NO; }]; } - (CGFloat)screenHeight { if (iPhone5) { return 568.0; } else { return 480.0; } } #pragma mark - actions - (IBAction)rotateBtnClicked:(id)sender { if (!self.isLandscape) { [self rotateToLandscapeRight]; } else { [self rotateToPortrait]; } } #pragma mark - handle notification - (void)changeFrames:(NSNotification *)notification { UIDeviceOrientation deviceOrientation = [[UIDevice currentDevice] orientation]; if (deviceOrientation == UIDeviceOrientationLandscapeRight) { [self rotateToLandscapeLeft]; } else if (deviceOrientation == UIDeviceOrientationLandscapeLeft) { [self rotateToLandscapeRight]; } else if (deviceOrientation == UIDeviceOrientationPortrait){ [self rotateToPortrait]; } } @end其中,rotateToLandscapeLeft/rotateToLandscapeRight/rotateToPortrait是视图旋转的核心方法。我们在viewDidLoad方法中注册了一个事件通知,当设备的物理旋转方向发生改变时,我们将调用方法changeFrames:来对视图进行相应的旋转,也可以通过点击某个按钮来旋转界面。可以看到,测试项目中还有一个UINavigationController的类别。类别中添加
#import "UINavigationController+Ext.h" @implementation UINavigationController (Ext) - (BOOL)shouldAutorotate { return NO; } @end
为什么要添加UINavigationController类别?因为旋转的时候我们需要同时去旋转statusBar(状态栏),要旋转statusBar必须在shouldAutorotate方法中返回NO。
运行测试项目并旋转设备,能看到我们已经成功手动控制界面旋转,且旋转的动画效果与系统默认的旋转效果是一模一样的。和之前那篇文章中提到的解决方法相比,有了更高的自由度,开发者能够随性控制界面的旋转。
测试工程:下载
相关文章推荐
- iOS视频全屏与界面旋转的控制
- NT_iOS笔记—iOS图片显示3_界面的手动旋转(UIDeviceOrientation和UIInterfaceOrientation)
- iOS开发中控制屏幕旋转,个别界面强制横屏
- iOS 9控制界面旋转
- iPhone自动旋转控制代码-IOS开发
- ios 强制某个界面旋转成横屏
- IOS屏幕旋转详解(自动旋转、手动旋转、兼容IOS6之前系统)
- ios 6 的变化 与 旋转屏幕控制
- iOS之浅谈纯代码控制UIViewController视图控制器跳转界面的几种方法
- 屏幕旋转--自动及手动控制(视频播放中setRequestedOrientation之后手机屏幕的旋转不触发onConfigurationChanged方法)
- Unity3D研究院之IOS触摸屏手势控制镜头旋转与缩放
- IOS触摸屏手势控制镜头旋转与缩放
- Unity3D 游戏引擎之IOS触摸屏手势控制镜头旋转与缩放(八)
- ios 手动控制开启、禁止屏幕旋转
- Unity3D研究院之IOS触摸屏手势控制镜头旋转与缩放
- 【转载】Unity3D研究院之IOS触摸屏手势控制镜头旋转与缩放
- unityios开发--触摸屏手势控制镜头旋转与缩放
- iPhone自动旋转控制代码-IOS开发
- iOS开发的一些小技术:让UIImage有缩放功能、控制log的输出、xcode修改文件注释、随机数的使用、在UIImageView 中旋转图像、在Quartz中如何设置旋转点、创建.plist文件并存储
- 代码控制界面:ios开发