天天看點

iOS:手寫代碼自動實作自動布局,即Auto Layout的使用

iOS6 之後,蘋果公司引進了Auto Layout,相比之前的autoresizing功能更強大,這也是蘋果公司為了未來不同機型未雨綢缪的措施。

這裡要注意幾點:

  1. 對子視圖的限制,若是基于父視圖,要通過父視圖去添加限制。
  2. 對子視圖進行自動布局調整,首先對UIView的一個屬性設定,這是因為如果我們用Interface Builder,勾選Ues Autolayout,這時autoresizingMask就會被Auto Layout 取代,在手寫代碼時,我們就需要手動控制,代碼如下

    [_shadow setTranslatesAutoresizingMaskIntoConstraints:NO]

  3. 在添加限制前,要先将子視圖添加到父視圖上。

    以下為例,oneImgView 上添加子視圖shadow,對shadow進行限制

@property (nonatomic, strong) UIImageView *shadow;
@property (nonatomic, strong) UIImageView *oneImgView;
[_shadow setTranslatesAutoresizingMaskIntoConstraints:NO]; // 使用自動布局
        [self.oneImgView addSubview:_shadow]; // 添加限制前要先将子視圖添加到父視圖上
        NSLayoutConstraint *constraint = [NSLayoutConstraint
                                          constraintWithItem:_shadow
                                          attribute:NSLayoutAttributeWidth
                                          relatedBy:NSLayoutRelationEqual
                                          toItem:self.oneImgView
                                          attribute:NSLayoutAttributeWidth
                                          multiplier:
                                          constant:];
        [self.oneImgView addConstraint:constraint];

        constraint = [
                      NSLayoutConstraint
                      constraintWithItem:_shadow
                      attribute:NSLayoutAttributeBottom
                      relatedBy:NSLayoutRelationEqual
                      toItem:self.oneImgView
                      attribute:NSLayoutAttributeBottom
                      multiplier:f
                      constant:f
                      ];
        [self.oneImgView addConstraint:constraint];
        constraint = [
                      NSLayoutConstraint
                      constraintWithItem:_shadow
                      attribute:NSLayoutAttributeHeight
                      relatedBy:NSLayoutRelationEqual
                      toItem:nil
                      attribute:NSLayoutAttributeHeight
                      multiplier:f
                      constant:f
                      ];
        [self.oneImgView addConstraint:constraint];
        constraint = [
                      NSLayoutConstraint
                      constraintWithItem:_shadow
                      attribute:NSLayoutAttributeLeft
                      relatedBy:NSLayoutRelationEqual
                      toItem:self.oneImgView
                      attribute:NSLayoutAttributeLeft
                      multiplier:f
                      constant:f
                      ];
        [self.oneImgView addConstraint:constraint];
           

關于函數

+(instancetype)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c;

蘋果的官方文檔是這麼描述的。

/* Create constraints explicitly.  Constraints are of the form "view1.attr1 = view2.attr2 * multiplier + constant" 
 If your equation does not have a second view and attribute, use nil and NSLayoutAttributeNotAnAttribute.
 */
           

是以你隻需要記住view1.attr1 = view2.attr2 * multiplier + constant就可以了

可視化格式語言限制(VFL)

除此之外iOS 8推出了一種新的限制方式——可視化格式語言限制,這種限制方式和中國古代的象形文字很相似。它可以一次添加多個限制,而且很直覺,但不是所有的限制都可以滿足的,維護也有一定的難度

代碼為例,如果我要實作shadow 距離父視圖左邊界為20,寬為40,距離頂部20,高度最小30,不能超過100

NSArray *constraints = nil;
        constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-20-[_shadow(==40)]|" options:NSLayoutFormatAlignAllLeft metrics:nil views:NSDictionaryOfVariableBindings(_shadow)];
        [self.oneImgView addConstraints:constraints];
        constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[_shadow(>=58)@100]" options:NSLayoutFormatAlignAllLeft metrics:nil views:NSDictionaryOfVariableBindings(_shadow)];
        [self.oneImgView addConstraints:constraints];
           
  1. format:這裡是你的VFL語句,比如:@”H:|[_shadow]|”(注意“-”預設父子視圖之間表示20px,同級視圖之間表示8px,但是如果是“-10-”則表示前後相距10,短線距離忽略)
  2. options:預設寫0,跟據需求去選擇你想要的枚舉
  3. metrics:字典, 你的VFL語句中使用了動态參數時,将參數名和對應的值為鍵值對寫在字典中,比如:@”H:|-[_shadow(==width)]-|”,表示這個_shadow的寬度為width,這是字典裡面找到key對就的值,如果沒有找到這個值,app就會crash.
  4. views:字典,你的VLF語句中使用到得所有view,用這個宏去添加NSDictionaryOfVariableBindings(view1,view2,view3…)

    上面代碼中VFL語句為:@”H:|[_shadow]|”,其中“|”表示父視圖的邊界

以下為VLF語句

|: 表示父視圖

-:表示距離

V: :表示垂直

H: :表示水準

>= :表示視圖間距、寬度和高度必須大于或等于某個值

<= :表示視圖間距、寬度和高度必須小宇或等于某個值

== :表示視圖間距、寬度或者高度必須等于某個值

@ :>=、<=、== 限制 最大為 1000

以下為例

|-[view]-|: 視圖處在父視圖的左右邊緣内

|-[view] : 視圖處在父視圖的左邊緣

|[view] : 視圖和父視圖左邊對齊

-[view]- : 設定視圖的寬度高度

|-30.0-[view]-30.0-|: 表示離父視圖 左右間距 30

[view(200.0)] : 表示視圖寬度為 200.0

|-[view(view1)]-[view1]-| :表示視圖寬度一樣,并且在父視圖左右邊緣内

V:|-[view(50.0)] : 視圖高度為 50

V:|-(==padding)-[imageView]->=0-[button]-(==padding)-| : 表示到父視圖左邊的距離為Padding,這兩個視圖間距必須大于或等于0并且距離底部父視圖為 padding。

[wideView(>[email protected])] :視圖的寬度為至少為60 不能超過 700

如果沒有聲明方向預設為 水準 V: