在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能做到,暫時我還沒有發現