您的位置:首页 > 移动开发 > IOS开发

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文件中添加代码,如下

#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 界面旋转