首页 > Personal > ios > IOS Orientation 详解
2015
04-02

IOS Orientation 详解

最近开发IOS遇到一个问题,
为了支持UI布局横屏竖屏,监听了
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notifyOrientation:) name:UIDeviceOrientationDidChangeNotification object:nil];

收到消息后
-(void)notifyOrientation:(NSNotification *)notify
中在做处理。
但是处理后发现有的时候横竖屏还是处理不对,发现
[[UIDevice currentDevice] orientation]
取得UIDeviceOrientation一共有7个值除了横竖还有
UIDeviceOrientationUnknown、UIDeviceOrientationFaceUp、UIDeviceOrientationFaceDown,
后两个是平放朝上和朝下,这样就会有问题,在处理时会出错,所以想到用
[[UIApplication sharedApplication] statusBarOrientation]
取得UIInterfaceOrientation用UI的反转代替Device的反转,看下定义
typedef NS_ENUM(NSInteger, UIInterfaceOrientation) {
UIInterfaceOrientationUnknown = UIDeviceOrientationUnknown,
UIInterfaceOrientationPortrait = UIDeviceOrientationPortrait,
UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,
UIInterfaceOrientationLandscapeLeft = UIDeviceOrientationLandscapeRight,
UIInterfaceOrientationLandscapeRight = UIDeviceOrientationLandscapeLeft
};
UIInterfaceOrientation只有横竖,而且横屏时左右和Device是颠倒的。用它就不需要考虑平放的情况了。

最后总结,需要注意UIDeviceOrientation只是设备状态,至于应用中是什么情况还是要以UIInterfaceOrientation为准。

需要注意的在IOS7 和 更早的版本中UIWindow的transform并不随UIInterfaceOrientation方向的变化而变化,而且[UIScreen mainScreen]的bounds和applicationFrame也不随UIInterfaceOrientation方向变化而变化,bounds包含status bar高度20,applicationFrame则不包含,如果隐藏status bar则二者一致。
而在IOS8中UIWindow会随UIInterfaceOrientation的变化而变,所以之前写的一个应用中在UIWindow上添加UIView就会出现问题,
UIWindow* window = [[[UIApplication sharedApplication] delegate] window];
[window addSubview:self.view];
解决上述问题,几种解决方法,
1. 如果一定要在UIWindow中添加UIView的话,在IOS7或以前的IOS版本中需要自己处理旋转问题,
UIInterfaceOrientation orientation = [[UIApplication sharedApplication]statusBarOrientation];
if (orientation == UIInterfaceOrientationLandscapeLeft) {
CGAffineTransform rotation = CGAffineTransformMakeRotation(3*M_PI/2);
[view setTransform:rotation];
}
if (orientation == UIInterfaceOrientationLandscapeRight) {
CGAffineTransform rotation = CGAffineTransformMakeRotation(M_PI/2);
[view setTransform:rotation];
}
if (orientation == UIInterfaceOrientationPortraitUpsideDown ) {
CGAffineTransform rotation = CGAffineTransformMakeRotation(M_PI);
[view setTransform:rotation];
}

2. 为view创建UIViewController,使用UIViewController处理旋转问题,在UIViewController中添加
– (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
并且UIViewController的view需要添加到UIWindow中
[window addSubview:self.view];
还需要保证UIViewController为UIWindow的主UIViewController,及第一个加入UIWindow中,
因为UIViewController继承自UIResponder,同一级别中只有第一个UIViewController能接受到上述消息。

3. 如果你的view不是第一个UIViewController,还可以直接把view加到UIWindow的第一个主view中,
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
[[window.subviews objectAtIndex:0] addSubview:self.view];

一般建议用第三种做法。

如果想单独控制一个view的Orientation可以实现UIViewController的
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll; // 表示支持全部方向
}
-(BOOL)shouldAutorotate
{
return YES;
}

最后编辑:
作者:wy182000
这个作者貌似有点懒,什么都没有留下。