在ios中获取设备当前方向的枚举有UIInterfaceOrientation和UIDeviceOrientation
,前者包含枚举
Unknown//未知
Portrait//屏幕竖直,home键在下面
PortraitUpsideDown//屏幕竖直,home键在上面
LandscapeLeft//屏幕水平,home键在左边
LandscapeRight//屏幕水平,home键在右边
后者的设备方向枚举为:
Unknown//未知
Portrait//屏幕竖直,home键在下面
PortraitUpsideDown//屏幕竖直,home键在上面
LandscapeLeft//屏幕水平,home键在左边
LandscapeRight //屏幕水平,home键在右边
FaceUp //屏幕向上摆放在桌面
FaceDown//屏幕向下摆放在桌面
两者都包含了相关方向,一般情况下使用前者的四个方向即可,但是在使用前者UIInterfaceOrientation的时候,发现存在一个bug。如,我要通过监听来获得屏幕的当前方向,代码是这样的
1 NSNotificationCenter.defaultCenter().addObserver(self, selector: "orientChange:", name: UIDeviceOrientationDidChangeNotification, object: nil)
func orientChange(noti:NSNotification){ switch self.interfaceOrientation{ case .LandscapeLeft: println("LandscapeLeft") case .LandscapeRight: println("LandscapeRight") case .Portrait: println("Portrait") case .PortraitUpsideDown: println("PortraitUpsideDown") case .Unknown: println("Unknown") default: println("default") } }
此时屏幕旋转,控制台就会打印出当前的设备方向,一般情况下,打印的都是正确的,但是如果旋转的过快,比如我的旋转方向顺序为
Portrait->LandscapeRight->PortraitUpsideDown
控制台打印的顺序应该是
Portrait->LandscapeRight->PortraitUpsideDown
但是设备在旋转过快的时候打印的结果是
Portrait->LandscapeRight->LandscapeRight
这会导致UI变的不可接受。虽然这种情况一般不出现,但是如果被用户发现,却是不可饶恕的错误
于是我拿UIDeviceOrientation进行了测试,
UIDeviceOrientation不管旋转的速度多快,都能很好的识别出设备的真实方向。
所以由此得出建议,在能使用UIDeviceOrientation的情况下,不要去使用UIInterfaceOrientation
是不是就完了呢?就这一个bug吗
不是的,还有一个问题
不管在使用UIDeviceOrientation 和UIInterfaceOrientation,如果旋转速度过快,还会导致一个致命的问题。那就是设备的长宽取出来是错误的
我使用的ipad是1024X768,这个可以通过view.bounds得到也可以通过UIScreen.mainScreen().bounds得到
我同样是从Portrait->LandscapeRight->PortraitUpsideDown,我在每一个方向下打印出获得的屏幕长宽,
理论上应该是(768,1024)->(1024,768)->(768,1024),但是旋转过快会导致这样的结果,你可能已经猜到:(768,1024)->(1024,768)->(1024,768)
也就是说我们可以得到正确的屏幕方向,但是有时候却得不到正确的屏幕长宽,为此我想到的办法是手动去设置屏幕的长宽。因为屏幕的尺寸的大小不会变,所以不管是长还是宽,数字大的肯定是设备横放时候的宽度,较小的是高度,于是:
//获取当前状态实际的屏幕尺寸 func getRealScreenSize(orientation:UIDeviceOrientation)->CGSize{ var size = UIScreen.mainScreen().bounds.size var w = size.width,h = size.height if size.width < size.height{ w = size.height h = size.width } switch orientation{ case .LandscapeLeft,.LandscapeRight: size = CGSize(width: w, height: h) case .Portrait,.PortraitUpsideDown: size = CGSize(width: h, height: w) default: println("a") } return size }
我用getRealScreenSize方法来替代view.bounds或UIScreen.mainScreen().bounds
通过这种方式便解决了以上的bug。可能还有很方便的底层api能做到,暂时我还没有发现