iOS ? 記——Autolayout

適配

什么是適配?
適應、兼容各種不同的情況,移動開發中,適配的常見種類,如系統適配,就是針對不同版本的操作系統進行適配。

屏幕適配

針對不同大小的屏幕尺寸進行適配
iOS 4:autoResizing做屏幕適配
iOS 6:autoLayout 使用最廣泛的屏幕適配
iOS 8:sizeClass 最新的屏幕適配
iPhone的尺寸: 3.5inch、4.0inch、4.7inch、5.5inch
iPad的尺寸: 7.9inch、9.7inch、12.9inch
屏幕的方向:橫向、豎向。

適配的歷史

4S以前:坐標都是寫死的,例如創建一個button,設置它的frame:
注意:之前高度寬度都是寫死的

Uibutton *btn = nil;
Btn.frame = CGRectMake(20,20,320,480);

點和像素

在用戶眼中,屏幕是由無數個像素組成的,像素越多,屏幕越清晰。
在開發者眼中,屏幕是由無數個點組成的,點又是由像素組成的,
像素越多,屏幕越清晰。

Paste_Image.png
Paste_Image.png

什么是Autolayout?

Autolayout是一種“自動布局”技術,專門用來布局UI界面的,Autolayout自iOS 6開始引入,由于Xcode 4的不給力,當時并沒有得到很大推廣。

自iOS 7(Xcode 5)開始,Autolayout的開發效率得到很大的提升,蘋果官方也推薦開發者盡量使用Autolayout來布局UI界面,Autolayout能很輕松地解決屏幕適配的問題。

Autoresizing(局限性很大不能很好的滿足開發者,所以有了Autolayout的產生),在Autolayout之前,有Autoresizing可以作屏幕適配,但局限性較大,有些任務根本無法完成。相比之下,Autolayout的功能比Autoresizing強大很多。

Autolayout的2個核心概念:

參照 約束

Paste_Image.png

Paste_Image.png

Paste_Image.png

Paste_Image.png

Autolayout的警告和錯誤

警告:控件的frame不匹配所添加的約束, 比如:

  • 約束控件的寬度為100, 而控件現在的寬度是110。

錯誤:缺乏必要的約束, 比如:

  • 只約束了寬度和高度, 沒有約束具體的位置。(就是只有給這個控件設置了寬度和高度,但是沒告訴它具體顯示在哪個位置,這時候會報錯)
  • 兩個約束沖突, 比如1個約束控件的寬度為100, 1個約束控件的寬度為110。
  • 如果使用autolayout來約束控件, 那fraem就失效了, 官方也不建議我們再設置frame了

代碼實現Autolayout

步驟:
1.利用NSLayoutConstraint類創建具體的約束對象
2.添加約束對象到相應的view上:

- (void)addConstraint:(NSLayoutConstraint *)constraint;
- (void)addConstraints:(NSArray *)constraints;

例如:

NSLayoutConstraint*blueRightLc = [NSLayoutConstraint constraintWithItem:
blueView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual 
toItem:redView attribute:NSLayoutAttributeLeft multiplier:1.0 
constant:-20];

NSLayoutConstraint

一個NSLayoutConstraint對象就代表一個約束.
創建約束對象的常用方法:

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

view1 :要約束的控件
attr1 :約束的類型(做怎樣的約束)
relation :與參照控件之間的關系
view2 :參照的控件
attr2 :約束的類型(做怎樣的約束)
multiplier :乘數
c :常量
注意點:
要先禁止autoresizing功能,設置view的下面屬性為NO,不設置否則無法實現。

view.translatesAutoresizingMaskIntoConstraints = NO;

添加約束之前,一定要保證相關控件都已經在各自的父控件上,
不用再給view設置frame。

自動布局的核心計算公式

obj1.property1 =(obj2.property2 * multiplier)+ constant value

Paste_Image.png

Paste_Image.png

Paste_Image.png

VFL語言

Paste_Image.png

VFL示例:

H:[cancelButton(72)]-12-[acceptButton(50)]
canelButton寬72,acceptButton寬50,它們之間間距12

H:[wideView(>=60@700)]
wideView寬度大于等于60point,該約束條件優先級為700(優先級最大值為1000,優先級越高的約束越先被滿足)

V:[redBox][yellowBox(==redBox)]
豎直方向上,先有一個redBox,其下方緊接一個高度等于redBox高度的yellowBox

H:|-10-[Find]-[FindNext]-[FindField(>=20)]-|
水平方向上,Find距離父view左邊緣默認間隔寬度,之后是FindNext距離Find間隔默認寬度;再之后是寬度不小于20的FindField,它和FindNext以及父view右邊緣的間距都是默認寬度。(豎線“|” 表示superview的邊緣)

VFL使用:

使用VFL來創建約束數組:

+ (NSArray *)constraintsWithVisualFormat:(NSString *)format 
options:(NSLayoutFormatOptions)opts metrics:(NSDictionary *)metrics 
views:(NSDictionary *)views;

format :VFL語句
opts:約束類型
metrics :VFL語句中用到的具體數值
views:VFL語句中用到的控件
創建一個字典(內部包含VFL語句中用到的控件)的快捷宏定義
NSDictionaryOfVariableBindings(...)

AutoResizing

注意點:不能跟autoLayout 共存
高度/寬度:跟著父控件的高度/寬度進行縮放
四根線:固定那個位置,一般兩根線就能確定一個位置
局限性:兄弟控件不能設置間距 ,只能是相對于父控件
使用代碼 實現AutoResizing,控件.autoresizingMask:
跟storyboard中相反的 ,storyboard中是固定那個方向,代碼是拉伸那個方向。

UIViewAutoresizingNone                 = 0,
UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,
UIViewAutoresizingFlexibleRightMargin  = 1 << 2,
UIViewAutoresizingFlexibleTopMargin    = 1 << 3,
UIViewAutoresizingFlexibleBottomMargin = 1 << 5
UIViewAutoresizingFlexibleHeight       = 1 << 4,
UIViewAutoresizingFlexibleWidth        = 1 << 1,
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容