你好,歡迎來到IOS教程網

 Ios教程網 >> IOS訊息 >> 關於IOS >> Autolayout基礎講解

Autolayout基礎講解

編輯:關於IOS

這兩天自學的時候,復習了下 autolayout。本來想來寫一篇文章記錄下學習內容,搜了一下寫的人真不少,也寫得挺不錯的。照理我就不用寫了,但心裡總有那麼一點點遺憾,這麼流行的東西,我博客裡怎麼能沒有呢?既然如此,那就多寫點基礎內容。

警告:博主為博文貼了十幾張圖片,查克拉耗盡,生命垂危,關注 MicroCai 或者送香吻一個就能喚醒博主,好人一生平安。

  • Autolayout 基礎
    • Interface Builder 介紹
      • Align(對齊)
      • Pin:設置相對大小和位置
      • Resolve Auto Layout Issues:解決 autolayout 問題
      • Resizing Behavior
      • SizeClass
        • 重寫布局
        • 使用 Xcode 6 預覽
    • VFL(Visual Format Language)
    • Autolayout 常見問題
    • Masonry:替代 Autolayout

Interface Builder 介紹

在 storyboard 界面的右下角,有這麼一排圖標

Autolayout基礎講解

鼠標放上去停留一小段時間,就會告訴你它們的作用,從左至右依次是:

  • Align:用來設置對齊相關的約束;
  • Pin:設置相對大小和位置;
  • Resolve Auto Layout Issues:解決 autolayout 問題;
  • Resizing Behavior:設置重置大小會如何影響其他對象;
 

Align(對齊)

Autolayout基礎講解

下面這些是兩個視圖層次中同一級的 View 的對齊。

Leading Edges:頭對齊
Trailing Edges:尾對齊
Top Edges:頂部對齊
Bottom Edges:底部對齊

Horizontal Centers:水平中心對齊
Vertical Centers:垂直中心對齊
BaseLines:基准線(默認 View 底部位置)水平對齊,用來對齊有文字的控件,如 UILabel、UIButton 等

 下面這些是 SuperView 和 SubView 的對齊,SuperView 是 SubView 的 Container

Horizontal Center in Container:View 的水平中心和容器的水平中心的相對距離
Vertical Center in Container:View 的垂直中心和容器的垂直中心的相對距離
在對齊數值的白色輸入框內,點擊右側下拉框可以選擇“Use Current Canvas Value”,意思是使用當前 Xib/Storyboard 內的差值。

最後一個 Update Frames 表示如何更新 frame,有三個選項,默認為 None 不更新

None:不更新 frame
Items of New Constraints:更新新添加的 frame
All Frames in Container:更新容器內所有的 frame

Pin:設置相對大小和位置

Autolayout基礎講解

最上面有四個矩形框和四條虛線,原來用過 auto resizing 的童鞋應該會比較眼熟。矩形框裡的數字表示當前的 View 到最近的 View (注意:不是 SuperView)邊緣的距離。

在矩形框下面有一行灰色字的可選項“Constrain to margins”,意思是在設置上述約束是相對於 margins 設置的,而 margin 默認距離是 16。如和上邊緣距離 306,加上 16,所以 View 的頂部和它上邊最近的 View 的距離是 312。

其他的選項

Width:設置寬度
Height:設置高度

Equal Widths:設置兩個同級 View 的寬度關系
Equal Heights:設置兩個同級 View 的高度關系
Aspect Ratio:設置 View 自身寬高比例

Align:和前面所講的 **Align** 一致。那為什麼 **Align** 還會出現在這邊呢?估計和 **Pin** 有關系,故而也放到這邊。

Resolve Auto Layout Issues:解決 autolayout 問題

Autolayout基礎講解

可以選擇要處理的 Views:當前選中的 Views 或 Controller 內所有的 Views

Update Frames:更新 frame 
Update Constraints:更新約束
Add Missing Constraints:添加遺漏的約束
Reset to Suggested Constraints:重置約束
Clear Constraints:清除約束

Resizing Behavior

Autolayout基礎講解

設置重置大小會如何影響其他對象,有兩個選項(默認已勾選)

Sublings and Ancestors:影響同級兄弟 Views 和祖先 Views
Descendants:影響後代 Views

(這個地方我也沒弄明白,我查了文檔和一些博客,都只是做了簡單文字說明,然後自己試了下勾選和未勾選的情況,還是找不到有什麼區別,所以也沒明白具體是如何影響。)

SizeClass

SizeClass 中文意思可以理解為尺寸等級,就是在 autolayout 的基礎上,加上屏幕尺寸類型的定義。SizeClass 的寬高有三種類型:Compact(緊湊)、Any(任意)、Regular(普通)

不同設備屏幕的寬高類型
Autolayout基礎講解

當你具體選擇尺寸時, IB 會顯示出當前選擇的屏幕尺寸的相關信息,如寬高類型,屏幕尺寸類型,這個尺寸適用於哪些設備等。

重寫布局

如果你設置的某種類型屏幕的約束布局,在其他類型屏幕下出現不符合意圖的布局時,可以重寫布局,即重新設置該屏幕類型下的布局。

如圖的 UIView 設置了 wAny|hAny 上下左右四個約束

Autolayout基礎講解

點擊這個 UIView,查看 Attribute Inspector 有個 install 選項被勾選上了。

Autolayout基礎講解

Installed/UnInstalled 表示的意思是當前布局是否被安裝在什麼類型的屏幕上。Installed/UnInstalled 前面如果沒有東西,表示布局是安裝在 wAny|hAny 類型的屏幕上。現在如果我們要單獨設置某種類型屏幕的布局可以點擊加號,選擇屏幕類型

Autolayout基礎講解

將新的屏幕類型的勾選取消掉,則當前布局在該類型下不起作用,此時就可以切換類型,重新設置所有約束。

若只想修改一條約束,也可以點擊 Size Inspector

Autolayout基礎講解

選擇 Constraints —— All 顯示所有約束,雙擊任意一條約束,會出現一個和之前類似的界面

Autolayout基礎講解

Installed 前面也有個加號,估計你也該猜到了,這裡的修改和之前也是類似的。

如果 Xcode 的 Inspector 一些選項前面有加號,就表明它可以被重寫,比如剛剛這幅圖中,Installed
選項上方的 Constant 前面也有加號,說明它也是可以被重寫的。類似的還有 UILabel 的 font,但是:與重寫布局不同,在不同的 size class 中改變文字的屬性始終會影響基礎布局中的文字。它不能像布局一樣,在不同的size class中設置不同的屬性值。我們通過下面的方法來解決這一問題。 參考:Swift自適應布局(Adaptive Layout)教程(二)。

使用 Xcode 6 預覽

在屏幕類型多了這麼多之後,做不同類型的屏幕適配也是需要花不少功夫。如果每次適配一種類型屏幕後,都要運行後才能查看效果,效率簡直太低下了。Xcode 6 提供了 preview 預覽功能,針對這個問題可以節省不少時間。

點擊 Xcode Tool Bar 的 Assistant Editor 按鈕,顯示另一個窗口

Autolayout基礎講解

選擇 Preview 展示預覽界面

Autolayout基礎講解

如果想在預覽中同時顯示不同類型的屏幕,可以在預覽界面的左下角點擊加號,選擇更多設備

Autolayout基礎講解

如果想要查看橫屏/豎屏,點擊設備下方的旋轉按鈕即可

Autolayout基礎講解

VFL(Visual Format Language)

不得不說,VFL 的語法比手寫 Constraints 的量少了很多,也有象形文字的感覺,但是和普通的 Swift 語法風格比起來實在不搭調。這個內容直接看 官方文檔 吧,都用圖表示出來,說明的挺清楚的。

Autolayout 常見問題

  1. 設置了 autolayout 之後,在代碼中還能用 self.someView.frame 修改 frame 嗎?
    不能
  2. 為什麼有些控件只設置 x、y 值約束,也不會出錯?
    UIKit 的一些控件如 UILabel、UIImageView 等有自適應特性,會根據內容自適應尺寸,所以不需要再約束其寬高。
  3. 同樣的約束用在 UIScrollView 和 UIImageViwe 上,為什麼會出現錯誤?
    參考 Nonomori 的文章:ScrollView 與 Autolayout

Masonry:替代 Autolayout

Masonry 是目前為止公認的 autolayout 最好的替代方案,語法簡潔、直觀,不會出現各種意外之外的布局。根據網上了解到的一些情況,Masonry 在大型項目中的效果比 autolayout 好很多。

舉個簡單的例子:要使一個 subview 填充 superview,但和 superview 的邊界間距(inset) 10 個像素。使用 NSLayoutConstraints 是這麼寫的

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],
]];
一個簡單的布局竟然寫了這麼多代碼,有種要死的感覺。用 Masonry 又是什麼樣子呢?

 
UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10);
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(superview.mas_top).with.offset(padding.top); //with is an optional semantic filler
make.left.equalTo(superview.mas_left).with.offset(padding.left);
make.bottom.equalTo(superview.mas_bottom).with.offset(-padding.bottom);
make.right.equalTo(superview.mas_right).with.offset(-padding.right);
}];
代碼少了至少一半以上,終於能緩過氣來了。但是還不夠,還能更少。

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

至尊寶:整個世界都清淨了!!!

Masonry 的 Github 地址

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved