適配
什么是適配?
適應、兼容各種不同的情況,移動開發中,適配的常見種類,如系統適配,就是針對不同版本的操作系統進行適配。
屏幕適配
針對不同大小的屏幕尺寸進行適配
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);
點和像素
在用戶眼中,屏幕是由無數個像素組成的,像素越多,屏幕越清晰。
在開發者眼中,屏幕是由無數個點組成的,點又是由像素組成的,
像素越多,屏幕越清晰。
什么是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
VFL語言
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,