天天看點

iOS6與iOS7螢幕适配 edgesForExtendedLayout

日常開發中, 在有導航欄的情況下, iOS6.0和 iOS7.0的布局在同樣的 frame下會呈現出不同的效果. 今天就來說一說 iOS6.0和 iOS7.0的螢幕适配, iOS6.0雖然久遠, 但是還是有一批這樣使用者的, 是以有時候還需要照顧到.

有導航欄時, 預設效果

UIView *aView = [[UIView alloc]initWithFrame:CGRectMake(, , , )];
    aView.backgroundColor = [UIColor redColor];
    [self.view addSubview:aView];
           

在沒有導航欄時, 如上寫的話效果一緻, 有導航欄時效果如下:

iOS6.0效果:

iOS6與iOS7螢幕适配 edgesForExtendedLayout

iOS7.0效果:

iOS6與iOS7螢幕适配 edgesForExtendedLayout

如何才能統一, 使iOS6.0和 iOS7.0螢幕适配

UIViewController 中有個參數

edgesForExtendedLayout

, 是控制邊緣延伸布局的.

iOS6此參數預設為

UIRectEdgeNone

,iOS7鼓勵全屏布局, 預設值很自然地是

UIRectEdgeAll

,四周邊緣均延伸,就是說,如果即使視圖中上有navigationBar,下有tabBar,那麼視圖仍會延伸覆寫到四周的區域。

edgesForExtendedLayout

@property(nonatomic,assign) BOOL extendedLayoutIncludesOpaqueBars NS_AVAILABLE_IOS(7_0); // Defaults to NO, but bars are translucent by default on 7_0.

This property is applied only to view controllers that are embedded in a container such as UINavigationController. The window’s root view controller does not react to this property. The default value of this property is UIRectEdgeAll.

這個枚舉如下:

typedef NS_OPTIONS(NSUInteger, UIRectEdge) {
    UIRectEdgeNone   = 0,
    UIRectEdgeTop    = 1 << 0,
    UIRectEdgeLeft   = 1 << 1,
    UIRectEdgeBottom = 1 << 2,
    UIRectEdgeRight  = 1 << 3,
    UIRectEdgeAll    = UIRectEdgeTop | UIRectEdgeLeft | UIRectEdgeBottom | UIRectEdgeRight
} NS_ENUM_AVAILABLE_IOS(7_0);
           

這個屬性适用于嵌入導航欄或者TabBar的控制器, 說明目前VC是否可以延伸。将iOS7也改為UIRectEdgeNone, 便可達到iOS6與iOS7的螢幕布局适配:

if ([[UIDevice currentDevice].systemVersion floatValue] >= ) {
        self.edgesForExtendedLayout = UIRectEdgeNone;
    }
           

contentInset

在控制器的view是UIScrollView, 如UITableView/UICollectionView中, 我們也可以通過contentInset參數來控制, 它是 UIScrollview 的屬性, 也是來控制内延的.是以也有了如下總結:

//控制器的view是普通的UIView,如 UIViewController , 通過edgesForExtendedLayout參數來增加内延, 使 iOS7以後達到 iOS6的效果
    if ([[UIDevice currentDevice].systemVersion floatValue] >= ) {
        self.edgesForExtendedLayout = UIRectEdgeNone;
    }

    //控制器的view是UIScrollView, 如UITableView/UICollectionView
    self.tableView.contentInset = UIEdgeInsetsMake(, , , );
    self.collectionView.contentInset = UIEdgeInsetsMake(, , , );
           

具體需要内延的方向和距離需要跟據開發中你遇到的情況和布局特點了決定的.

無導航欄情況下适配

// iOS7 && 沒有包裝導航控制器
    if ([[UIDevice currentDevice].systemVersion floatValue] >=  && self.navigationController == nil) {
        CGFloat top = [self.topLayoutGuide length];

        //控制器的view是UIScrollView, 如UITableView/UICollectionView
        if ([self.view isKindOfClass:[UIScrollView class]]) {
            UIScrollView *scroll = (UIScrollView *)self.view;
            scroll.contentInset = UIEdgeInsetsMake(top, scroll.contentInset.left, scroll.contentInset.bottom, scroll.contentInset.right);
        }else{
            //控制器的view是普通的UIView,如 UIViewController
            CGRect bounds = self.view.bounds;
            bounds.origin.y =  - top;
            self.view.bounds = bounds;
        }
    }
           

延伸閱讀

假如在 iOS7中布局一個 UITableviewController 或者在 UIViewController 中布局一個tableview 的時候, 你發現會有一些與上述不太一緻的問題.請了解:

automaticallyAdjustsScrollViewInsets/extendedLayoutIncludesOpaqueBars

給你的TableView一個最合适的布局