你好,歡迎來到IOS教程網

 Ios教程網 >> IOS訊息 >> 關於IOS >> iOS AutoLayout與AutoSizing

iOS AutoLayout與AutoSizing

編輯:關於IOS
[收起] 文章目錄
  • 1. Autolayout 與 Autosizing的區別
  • Autolayout的使用
  • 關鍵還是實踐

在iPhone Retina發布之前,還沒有AutoLayout,因為屏幕只有一種尺寸。
當iPhone Retina發布之後,我沒有用上AutoLayout,因為屏幕尺寸是用點來表示,布局寫起來沒什麼不同。
當iPhone 5發布之後,屏幕尺寸終於加長了,但是由於有AutoSizing,所以我還是可以不用AutoLayout。
現在,iPhone 6和6 Plus發布了,屏幕又大了,我不得不開始考慮是否要使用AutoLayout。

1. Autolayout 與 Autosizing的區別

雖然自iOS6之後,蘋果推薦我們使用Autolayout布局,並且在Xib和Storyboard中默認幫我們打開了這個選項,但是在開發過程中,我們偏向於使用Autosizing,並且手動取消掉Autolayout,原因在於,Autolayout太繁瑣復雜,而Autosizing簡單並且能滿足大部分的需求。

Autosizing適用的情況

當父視圖被拉伸的時候,子視圖能夠適配父視圖的新大小。其原理是,子視圖有一個masks,用於指定與父視圖上下左右邊緣的距離,以及自身寬高的關系。

比如,指定子視圖的右邊緣緊跟著父視圖的右邊緣,那麼父視圖變大之後,子視圖還是貼在父視圖的右邊。

這在大部分簡單布局情況下非常有效。

Autosizing的不足

使用Autosizing,有一個前提,就是子視圖的Frame是固定的,至少寬高是固定的,或者跟隨著父視圖的Frame變化。但是,如果希望多個子視圖與父視圖的邊距固定,大小自動調整,Autosizing就愛莫能助了。

原因在於:Autosizing無法智能計算多個子View各自的Frame。

比如,我們希望在豎屏下布局是這樣:

iOS AutoLayout與AutoSizing

並且在橫屏下布局是這樣:

iOS AutoLayout與AutoSizing

除了手寫代碼調整Frame,單獨用Autosizing是無法做到的。這時候就需要借助強大的Autolayout了。

Autolayout的優點

Autolayout使用約束來決定每個View的坐標、大小,約束可以針對SuperView,也可以針對其他任意一個SubView。

使用自動布局,你可以表達出視圖與視圖之間的關系,而不是明確地指定每個視圖的Frame。通過約束,視圖會自動計算它們應該呆在哪個位置,只要約束足夠多,它們也能自動計算自己的大小。

只要指定了約束,無論屏幕大小怎麼變化,它們都能自適應,這就是Autolayout的優點:媽媽再也不用擔心你手寫布局代碼啦!也不用擔心你為了適配各種屏幕大小而加班了。

Autolayout的缺點

Autolayout唯一的缺點就在於:過於復雜,較難上手。

使用Autolayout,還是Autosizing?

取決於項目需求。如果Autosizing完全能滿足開發需求,那麼就沒必要使用復雜的Autolayout。但是,如果你已經被適配各種屏幕大小折騰得不成人形了,那麼就要早日投入到Autolayout的懷抱了。

Autolayout的使用

首先要改變自己對布局的思考方式。你應該忘掉Frame,需要考慮的是subView A與subView B的上下左右的關系,以及與superView的關系。

借助XCode

在Xcode5之後,蘋果已經盡力讓開發者能更方便地使用Autolayout了。
通過Xcode–>Editor–>Pin/Align菜單為視圖添加約束即可。

在XCode中除了通過菜單,還可以通過可視化的方式添加約束:

iOS AutoLayout與AutoSizing

如果你添加的約束不足以表達某個View的位置大小,XCode還會以黃色的輔助線發出警告,十分好用。

手寫約束Constraint

XCode雖然強大,但是有時候我們也許希望借助代碼來寫Constraint。

加入你希望一個子view跟隨父view的大小,但是與邊距有10個點的距離:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
UIView *superview = self;

UIView *view1 = [[UIView alloc] init];
view1.translatesAutoresizingMaskIntoConstraints = NO;
view1.backgroundColor = [UIColor greenColor];
[superview addSubview:view1];

UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10);

[superview addConstraints:@[

    //view1 constraints
    [NSLayoutConstraint constraintWithItem:view1
                                 attribute:NSLayoutAttributeTop
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:superview
                                 attribute:NSLayoutAttributeTop
                                multiplier:1.0
                                  constant:padding.top],

    [NSLayoutConstraint constraintWithItem:view1
                                 attribute:NSLayoutAttributeLeft
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:superview
                                 attribute:NSLayoutAttributeLeft
                                multiplier:1.0
                                  constant:padding.left],

    [NSLayoutConstraint constraintWithItem:view1
                                 attribute:NSLayoutAttributeBottom
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:superview
                                 attribute:NSLayoutAttributeBottom
                                multiplier:1.0
                                  constant:-padding.bottom],

    [NSLayoutConstraint constraintWithItem:view1
                                 attribute:NSLayoutAttributeRight
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:superview
                                 attribute:NSLayoutAttributeRight
                                multiplier:1
                                  constant:-padding.right],

 ]];

每個約束都是這樣的長長一串代碼,設想一下需要添加6個約束的話……

幸好有了這個開源庫:Masonry。

使用這個庫,代碼添加約束就可以簡介如下:

1
2
3
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
    make.edges.equalTo(superview).with.insets(padding);
}];

更新約束

比如,我們自己實現了一個圖文混排的TextView,添加到Xib時我們還不知道其高度,需要在代碼中計算,那麼就需要在代碼裡更新約束,如:

1
2
3
4
5
6
7
8
9
10
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *richTextHeightConstraint;

...

- (void)relayout
{
    self.richTextHeightConstraint.constant = self.richTextView.frame.size.height;

    [self needsUpdateConstraints];
}

關鍵還是實踐

多說無益,貴在實踐。只要有意識地去使用了一次,自然就會了。

參考鏈接

  • Beginning Auto Layout Tutorial in iOS 7: Part 1
  • Beginning Auto Layout Tutorial in iOS 7: Part 2
  • 開始iOS 7中自動布局教程 一
  • 開始iOS 7中自動布局教程 二
  • 從此愛上iOS Autolayout
  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved