【原】UI隨設備旋轉從iOS6到iOS8的適配策略

- (void)statusBarOrientationChange:(NSNotification *)notification
{
    WClassAndFunctionName;
    UIInterfaceOrientation oriention = [UIApplication sharedApplication].statusBarOrientation;
    [self adaptUIBaseOnOriention:oriention];
}

 

通常狀況下,關於屏幕旋轉的適配用view自帶的autoresizingmask屬性就能輕鬆適配寬度以及邊距,並且從iOS6到iOS8通吃。不過,前提是「通常狀況下」。當你須要在橫屏與豎屏狀態下讓你封裝的view有不一樣的佈局,那autoresizingMask屬性就顯得力不從新了。這也是本文要解決的主要問題。ios

顯然,檢測視圖旋轉事件是必需要作的。通常咱們封裝一個自定義控件,老是但願調用者能夠輕鬆的調用它,所以檢測視圖旋轉也應該在控件內作。佈局

開始檢測視圖旋轉。spa

在init方法中註冊通知server

- (void)registerListeningDeviceOriention
{
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(statusBarOrientationChange:)
                                                 name:UIApplicationDidChangeStatusBarOrientationNotification
                                               object:nil];
}

 一旦屏幕產生旋轉,則調用statusBarOrientionChange:方法。好比:blog

- (void)statusBarOrientationChange:(NSNotification *)notification
{
    WClassAndFunctionName;
    UIInterfaceOrientation oriention = [UIApplication sharedApplication].statusBarOrientation;
    [self adaptUIBaseOnOriention:oriention];//好比改變self.frame
}

然而,事情並非那麼順利跟想固然的!當你滿懷信心地在adaptUIBaseOnOriention方法中根據oriention作佈局後會發現,iOS8跑出來的效果很完美,而非iOS8版本卻亂七八糟。不少時候自定義view(如下簡稱superview)的subviews的佈局要依賴於superview的size。因此一旦superview的frame沒有適配好,那看起來就亂七八糟了!爲何會出現上述差別呢?根本緣由是statusBarOrientationChange的觸發時機依賴於ios版本。打log後發現,iOS8及以上的版本,statusBarOrientationChange在旋轉結束後調用;在iOS8如下的版本,statusBarOrientationChange在旋轉前調用。而若是你在statusBarOrientationChange方法中想固然地去讀取當前的設備高度跟寬度,那必然產生差別!事件

整體思路是沒錯的,下一步就是在statusBarOrientationChange裏面對當前的設備方向以及系統版本進行判斷,這樣才能取到真正的設備高度跟寬度,真正的設備高度寬度對於佈局是相當重要的!it

    CGFloat windowWidth = kDeviceWindowWidth4Panel;//iOS8不用更改
    CGFloat windowHeight = kDeviceWindowHeight4Panel;
    if (!IsIOS8orAbove) {
        windowWidth = (!kIsDeviceLandscape) ? kDeviceWindowWidth4Panel:kDeviceWindowHeight;
        windowHeight = (!kIsDeviceLandscape) ? kDeviceWindowHeight4Panel:(kDeviceWindowWidth - (IsIOS7orAbove ? 0 : kSystemStatusBarHeight));
    }

 其實,本質上能夠簡述爲:iOS8上windowSize取的是當前時刻的windowSize值,所以能夠直接賦值;iOS8如下的windowSize取得是下一時刻旋轉後的值,至關於預判了io

最後一點須要注意的地方是,若是你須要在statusBarOrientationChange方法中手動改變superview的frame,那請把init方法中的autoresizingMask屬性所有註釋掉,由於二者是衝突的,尤爲是在iOS8如下。由於在iOS8如下本質上是在旋轉以前就將全部的subviews的佈局更新爲旋轉後的狀態了,這樣翻轉過去就能正常顯示。若是你加了autoresizingMask屬性,那系統會根據旋轉前最後一刻的狀態來適配,這樣旋轉後就羣魔亂舞了。class

相關文章
相關標籤/搜索