关于UIInterfaceOrientation的一个bug

在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( w, height: h)
  
        case .Portrait,.PortraitUpsideDown:
            size = CGSize( h, height: w)
        default:
            println("a")
        }
        return size
    }

我用getRealScreenSize方法来替代view.bounds或UIScreen.mainScreen().bounds

通过这种方式便解决了以上的bug。可能还有很方便的底层api能做到,暂时我还没有发现

 


 





原文地址:https://www.cnblogs.com/JimmyBright/p/4323955.html