iOS 經常使用佈局方式之Autoresizing

級別: ★★☆☆☆
標籤:「iOS佈局」「iOS autoresizing」「autoresizingMask」
做者: Xs·H
審校: QiShare團隊
php

沐靈洛 線下分享iOS UIButton根據內容自動佈局時,有和前端同窗討論到iOS的經常使用佈局方式。討論過程十分熱鬧,不容易記錄,但做者認爲討論結果有必要記錄一下,但願能幫助到一些同窗。 做者將iOS經常使用佈局方式概括爲Frame、Autoresizing、Constraint、StackView和Masonry五種,並將逐一介紹。 本篇文章介紹Autoresizing。前端

autoresizing是iOS較早版本中出現的屏幕適配技術。當時,iOS設備機型少、app界面佈局簡單,autoresizing能夠較好地完成好比橫豎屏之類的視圖適配需求。在QiShare的項目中,autoresizing常與frame結合着使用來達到某些適配效果。好比,與上篇文章對比,用autoresizing能夠更快速地實現淺灰色contentView徹底覆蓋self.view並與之一塊兒旋轉的效果,代碼以下。git

- (void)viewDidLoad {
    
    [super viewDidLoad];
    
    _contentView = [[QiAutoresizingContentView alloc] initWithFrame:self.view.bounds];
    _contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    _contentView.backgroundColor = [UIColor lightGrayColor];
    [self.view addSubview:_contentView];
}
複製代碼

在上述代碼中,contentView的autoresizingMask屬性起到了決定性做用。咱們來認識下這個屬性。github

@property(nonatomic) UIViewAutoresizing autoresizingMask;    // simple resize. default is UIViewAutoresizingNone
複製代碼
typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {
    UIViewAutoresizingNone                 = 0,
    UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,
    UIViewAutoresizingFlexibleWidth        = 1 << 1,
    UIViewAutoresizingFlexibleRightMargin  = 1 << 2,
    UIViewAutoresizingFlexibleTopMargin    = 1 << 3,
    UIViewAutoresizingFlexibleHeight       = 1 << 4,
    UIViewAutoresizingFlexibleBottomMargin = 1 << 5
};
複製代碼

contentView的autoresizingMask屬性是一個位移枚舉UIViewAutoresizing。UIViewAutoresizing將視圖分爲了LeftMargin(相對於父視圖的左邊距)、RightMargin(相對於父視圖的右邊距)、TopMargin(相對於父視圖的上邊距)、BottomMargin(相對於父視圖的下邊距)、Width(視圖自身的寬)和Height(視圖自身的高)6個屬性。在不設置autoresizingMask時默認使用UIViewAutoresizingNone賦值。當將autoresizingMask設置爲某一個或多個值後,即設定該view的對應屬性能夠隨着父視圖的變化而變化。bash

好比在上述代碼中,contentView的autoresizingMask被賦值爲UIViewAutoresizingFlexibleWidth和UIViewAutoresizingFlexibleHeight,即設定contentView除了Width和Height能夠隨着self.view的變化而變化外,其他4個屬性都被固定住了,因此能達到預期的效果,以下。微信

接下來,做者嘗試使用autoresizing實現上篇文章中4等分的效果,代碼以下。app

- (instancetype)initWithFrame:(CGRect)frame {
    
    self = [super initWithFrame:frame];
    
    if (self) {
        
        CGFloat margin = 20.0;
        CGFloat padding = 20.0;
        CGFloat width = (self.bounds.size.width - margin * 2 - padding) / 2;
        CGFloat height = (self.bounds.size.height - margin * 2 - padding) / 2;
        
        _subView1 = [[UIView alloc] initWithFrame:CGRectMake(margin, margin, width, height)];
        _subView1.backgroundColor = [[UIColor redColor] colorWithAlphaComponent:.6];
        [self addSubview:_subView1];
        
        _subView2 = [[UIView alloc] initWithFrame:CGRectMake(margin + width + padding, margin, width, height)];
        _subView2.backgroundColor = [[UIColor greenColor] colorWithAlphaComponent:.6];
        [self addSubview:_subView2];
        
        _subView3 = [[UIView alloc] initWithFrame:CGRectMake(margin, margin + height + padding, width, height)];
        _subView3.backgroundColor = [[UIColor blueColor] colorWithAlphaComponent:.6];
        [self addSubview:_subView3];
        
        _subView4 = [[UIView alloc] initWithFrame:CGRectMake(margin + width + padding, margin + height + padding, width, height)];
        _subView4.backgroundColor = [[UIColor yellowColor] colorWithAlphaComponent:.6];
        [self addSubview:_subView4];
        
        _subView1.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin;
        _subView2.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin;
        _subView3.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin;
        _subView4.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin;
    }
    
    return self;
}
複製代碼

實現的效果圖以下。佈局

觀察上圖,在旋轉屏幕至橫屏後,4個subView之間的間距出了問題。這是由於UIViewAutoresizing枚舉中的6個值都是相對於父視圖的,不能實現同級視圖之間存在約束關係的場景需求。動畫

要實現同級視圖之間的約束需求,閱讀下篇文章要講的Constraint會大有幫助。 另外,做者對contentView作了一個縮放動畫,能夠更好地觀察視圖的變化狀況。具體細節能夠在QiLayoutDemo中查看。ui


小編微信:可加並拉入《QiShare技術交流羣》。

關注咱們的途徑有:
QiShare(簡書)
QiShare(掘金)
QiShare(知乎)
QiShare(GitHub)
QiShare(CocoaChina)
QiShare(StackOverflow)
QiShare(微信公衆號)

推薦文章:
iOS UIButton根據內容自動佈局
iOS 指定初始化方法
UIView中的hitTest方法
奇舞週刊

相關文章
相關標籤/搜索