適配
什么是適配?
適應(yīng)、兼容各種不同的情況
移動(dòng)開(kāi)發(fā)中,適配的常見(jiàn)種類
系統(tǒng)適配
針對(duì)不同版本的操作系統(tǒng)進(jìn)行適配
屏幕適配
針對(duì)不同大小的屏幕尺寸進(jìn)行適配
iOS 4:autoResizing做屏幕適配
iOS 6 autoLayout 使用最廣泛的屏幕適配
iOS 8 sizeClass 最新的屏幕適配
屏幕適配
iPhone的尺寸
3.5inch、4.0inch、4.7inch、5.5inch
iPad的尺寸
7.9inch、9.7inch
屏幕方向
豎屏
橫屏
適配的歷史:
4S以前:
坐標(biāo)都是寫(xiě)死的
Uibutton *btn = nil;
Btn.frame = CGRectMake(20,20,320,480);
注意:之前高度寬度都是寫(xiě)死的
點(diǎn)和像素
在用戶眼中
屏幕是由無(wú)數(shù)個(gè)像素組成的
像素越多,屏幕越清晰
在開(kāi)發(fā)者眼中
屏幕是由無(wú)數(shù)個(gè)點(diǎn)組成的,點(diǎn)又是由像素組成的
像素越多,屏幕越清晰


什么是Autolayout ?
Autolayout是一種“自動(dòng)布局”技術(shù),專門用來(lái)布局UI界面的
Autolayout自iOS 6開(kāi)始引入,由于Xcode 4的不給力,當(dāng)時(shí)并沒(méi)有得到很大推廣
自iOS 7(Xcode 5)開(kāi)始,Autolayout的開(kāi)發(fā)效率得到很大的提升
蘋(píng)果官方也推薦開(kāi)發(fā)者盡量使用Autolayout來(lái)布局UI界面
Autolayout能很輕松地解決屏幕適配的問(wèn)題
簡(jiǎn)介
Autoresizing(局限性很大不能很好的滿足開(kāi)發(fā)者,所以有了Autolayou的產(chǎn)生)
在Autolayout之前,有Autoresizing可以作屏幕適配,但局限性較大,有些任務(wù)根本無(wú)法完成
相比之下,Autolayout的功能比Autoresizing強(qiáng)大很多
Autolayout的2個(gè)核心概念
參照
約束




Autolayout的警告和錯(cuò)誤
警告
控件的frame不匹配所添加的約束,
比如
比如約束控件的寬度為100,
而控件現(xiàn)在的寬度是110
錯(cuò)誤
缺乏必要的約束, 比如
只約束了寬度和高度,
沒(méi)有約束具體的位置
(就是只有給這個(gè)控件設(shè)置了寬度和高度,但是沒(méi)告訴它具體顯示在哪個(gè)位置,這時(shí)候會(huì)報(bào)錯(cuò))
兩個(gè)約束沖突, 比如
1個(gè)約束控件的寬度為100, 1個(gè)約束控件的寬度為110
代碼實(shí)現(xiàn)Autolayout
代碼實(shí)現(xiàn)Autolayout的步驟
利用NSLayoutConstraint類創(chuàng)建具體的約束對(duì)象
添加約束對(duì)象到相應(yīng)的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];
[self.view
addConstraint:blueRightLc];
NSLayoutConstraint
一個(gè)NSLayoutConstraint對(duì)象就代表一個(gè)約束
創(chuàng)建約束對(duì)象的常用方法
+(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 :與參照控件之間的關(guān)系
view2 :參照的控件
attr2 :約束的類型(做怎樣的約束)
multiplier :乘數(shù)
c :常量
代碼實(shí)現(xiàn)Autolayout的注意點(diǎn)
要先禁止autoresizing功能,設(shè)置view的下面屬性為NO,不設(shè)置否則無(wú)法實(shí)現(xiàn)
view.translatesAutoresizingMaskIntoConstraints= NO;
添加約束之前,一定要保證相關(guān)控件都已經(jīng)在各自的父控件上
不用再給view設(shè)置frame
自動(dòng)布局的核心計(jì)算公式
自動(dòng)布局的核心計(jì)算公式
obj1.property1 =(obj2.property2 * multiplier)+ constant
value




VFL示例
H:[cancelButton(72)]-12-[acceptButton(50)]
canelButton寬72,acceptButton寬50,它們之間間距12
H:[wideView(>=60@700)]
wideView寬度大于等于60point,該約束條件優(yōu)先級(jí)為700(優(yōu)先級(jí)最大值為1000,優(yōu)先級(jí)越高的約束越先被滿足)
V:[redBox][yellowBox(==redBox)]
豎直方向上,先有一個(gè)redBox,其下方緊接一個(gè)高度等于redBox高度的yellowBox
H:|-10-[Find]-[FindNext]-[FindField(>=20)]-|
水平方向上,F(xiàn)ind距離父view左邊緣默認(rèn)間隔寬度,之后是FindNext距離Find間隔默認(rèn)寬度;再之后是寬度不小于20的FindField,它和FindNext以及父view右邊緣的間距都是默認(rèn)寬度。(豎線“|” 表示superview的邊緣)
VFL的使用
使用VFL來(lái)創(chuàng)建約束數(shù)組
(NSArray *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(NSDictionary
*)metrics views:(NSDictionary *)views;
format :VFL語(yǔ)句
opts :約束類型
metrics :VFL語(yǔ)句中用到的具體數(shù)值
views :VFL語(yǔ)句中用到的控件
創(chuàng)建一個(gè)字典(內(nèi)部包含VFL語(yǔ)句中用到的控件)的快捷宏定義
NSDictionaryOfVariableBindings(...)
基于Autolayout的動(dòng)畫(huà):
在修改了約束之后,只要執(zhí)行下面代碼,就能做動(dòng)畫(huà)效果
[UIView animateWithDuration:1.0 animations:^{
[添加了約束的view layoutIfNeeded];(強(qiáng)制自動(dòng)布局)
}];
Masonry
目前最流行的Autolayout第三方框架
用優(yōu)雅的代碼方式編寫(xiě)Autolayout
省去了蘋(píng)果官方惡心的Autolayout代碼
大大提高了開(kāi)發(fā)效率
框架地址:
https://github.com/SnapKit/Masonry
mas_equalTo和equalTo
默認(rèn)情況下
mas_equalTo有自動(dòng)包裝功能,比如自動(dòng)將20包裝為@20
equalTo沒(méi)有自動(dòng)包裝功能
如果添加了下面的宏,那么mas_equalTo和equalTo就沒(méi)有區(qū)別
define MAS_SHORTHAND_GLOBALS
// 注意:這個(gè)宏一定要添加到#import "Masonry.h"前面
mas_width和width
默認(rèn)情況下
width是make對(duì)象的一個(gè)屬性,用來(lái)添加寬度約束用的,表示對(duì)寬度進(jìn)行約束
mas_width是一個(gè)屬性值,用來(lái)當(dāng)做equalTo的參數(shù),表示某個(gè)控件的寬度屬性
如果添加了下面的宏,mas_width也可以寫(xiě)成width
define MAS_SHORTHAND
mas_height、mas_centerX以此類推
可有可無(wú)的用法
以下方法都僅僅是為了提高可讀性,可有可無(wú)
-
(MASConstraint*)with {
return
self;
}
-
(MASConstraint*)and {
return
self;
}
***********************NO6******************************
***********************NO6******************************
- 適配的歷史
4s 以前 不需要適配
坐標(biāo)都是寫(xiě)死的
[uiScreen mainScreen ].bounds.size
UIButton *btn = nil;
btn.frame = CGRectMake(20,20,320,480)
ios 4
autoResizing 做屏幕適配
ios 6
autoLayout 使用最廣泛的屏幕適配
ios 8
sizeClass 最新的屏幕適配
- autoResizing
注意點(diǎn) 不能跟autoLayout 共存
高度/寬度 跟著父控件的高度/寬度進(jìn)行縮放
四根線 固定那個(gè)位置 一般兩根線就能確定一個(gè)位置
局限性 兄弟控件不能設(shè)置間距 只能是相對(duì)于父控件
使用代碼 實(shí)現(xiàn)autoResizing 控件.autoresizingMask與storyboard中相反的 storyboard中是 固定那個(gè)方向 代碼是拉伸那個(gè)方向
UIViewAutoresizingNone = 0,
UIViewAutoresizingFlexibleLeftMargin = 1 << 0,
UIViewAutoresizingFlexibleRightMargin = 1 << 2,
UIViewAutoresizingFlexibleTopMargin = 1 << 3,
UIViewAutoresizingFlexibleBottomMargin = 1 << 5
UIViewAutoresizingFlexibleHeight = 1 << 4,
UIViewAutoresizingFlexibleWidth = 1 <<1,
- autoLayout:
概念
1. 參照
相對(duì)哪個(gè)控件設(shè)置約束
哪個(gè)控件離當(dāng)前空間最近,就參照哪個(gè)控件
2. 約束
尺寸
寬高
位置
xy
trailing 右邊
leading 左邊
思路
1. 如果是兩個(gè)控件的話 那么先搞定一個(gè)
4.autoLayout使用代碼布局
autoLayout 與 autoResizing 不能共存
view.translatesAutoresizingMaskIntoConstraints = NO;(關(guān)閉autoResizing功能)
使用NSLayoutConstrain 調(diào)用 constrainWithItem
第一個(gè)參數(shù) 需要約束的控件
第二個(gè)參數(shù) 控件的屬性
第三個(gè)參數(shù) 等于 / <= / 大于等于
第四個(gè)參數(shù) 相對(duì)那個(gè)控件的約束
第五個(gè)參數(shù) 相對(duì)哪個(gè)控件的屬性
第六個(gè)參數(shù) multiplier 乘以??
第七個(gè)參數(shù) 常量 需要加還是減
注意點(diǎn) 以上操作哪個(gè)控件最大 就添加到哪個(gè)控件上,如果是兄弟那么就添加到老爸身上, 同一個(gè)爺爺?shù)牟煌陌职?br> 添加到爺爺身上
"添加約束到最大的控件上"
- vfl 布局子控件
抽象語(yǔ)言知道是神馬東西就可以了
H:|(控制器左邊)-20(間距)-redView-20(間距)-[blueView(顯示的控件)(==redView(控件的寬度等于紅色控件的寬度))]-20-|(控制器的右邊)
使用NSLayoutConstrain constraintsWithVisualFormat
第一個(gè)參數(shù) 水平或者是垂直方向的約束(字符串)
第二個(gè)參數(shù) 對(duì)齊的選項(xiàng)
第三個(gè)參數(shù) 使用到數(shù)字可以添加到字典中
第四個(gè)參數(shù) 將所有的控件的添加到字典中, 鍵值對(duì)
名字都是一樣的
"添加數(shù)組到self.view"
6.masonry使用
使用步驟
1. 導(dǎo)入masonry的頭文件
2. A控件需要約束
使用A 調(diào)用mas_makeConstrain
在block中設(shè)置約束
make 就相當(dāng)于
調(diào)用者(控件)
- 優(yōu)先級(jí)
& 動(dòng)畫(huà)
優(yōu)先級(jí)最高是的1000
最低的是0
只要是優(yōu)先級(jí)小于1000的 那么就第二次執(zhí)行(當(dāng)最高優(yōu)先級(jí)不存在)
動(dòng)畫(huà)
當(dāng)界面發(fā)生改變的時(shí)候 如果需要?jiǎng)赢?huà)重新布局
[self.view layoutIfNeeded]
**************************筆記****************************
注意:
如果使用autolayout來(lái)約束控件,
那fraem就失效了, 官方也不建議我們?cè)僭O(shè)置frame了
寬度: 100
高度: 100
水平居中: X
垂直居中: Y
注意: 如果利用autolayout約束一個(gè)控件, 和我們以前使用frame約束控件一樣, 必須設(shè)置寬度/高度/X/Y , 如果缺少某一個(gè)約束就會(huì)報(bào)錯(cuò), 報(bào)錯(cuò)有可能會(huì)引發(fā)一些未知的bug
如果有紅色警告:
代表缺少約束
如果有黃色警告:
代表控件當(dāng)前的位置大小和約束的位置大小不一樣
距離頂部: 20 相當(dāng)于設(shè)置了Y
距離左邊:20 相當(dāng)于設(shè)置了X
距離右邊:20 相當(dāng)于設(shè)置了寬度
距離底部:20 相當(dāng)于設(shè)置了高度
注意:
在使用Autolayout時(shí),最好給每個(gè)控件起一個(gè)名稱, 方便閱讀
紅色:
距離左邊:20 X
距離底部:20 Y
高度: 50
寬度:
紅色距離藍(lán)色有20的間隙
設(shè)置紅色的寬度和藍(lán)色的寬度一樣
藍(lán)色:
距離右邊:20 X
距離底部:20 Y
高度: 50
寬度:
iOS8,默認(rèn)情況下,
左右兩邊會(huì)留出一段距離,,
紅色:
距離底部和左邊20 x/y
高度: 50
紅色距離藍(lán)色20 ((自動(dòng)根據(jù)屏幕的寬度- 紅色左邊的20 + 藍(lán)色右邊的20 + 紅色和藍(lán)色之間的20 ) / 2)
藍(lán)色:
距離右邊20 x
Y: 設(shè)置藍(lán)色的頂部和紅色對(duì)齊
高度: 設(shè)置藍(lán)色的底部和紅色對(duì)齊
寬度: 50
藍(lán)色:
距離頂部:20 Y
距離左邊:20 X
距離右邊:20 寬
高度: 50
紅色:
高度和藍(lán)色一樣 高度
紅色右邊和藍(lán)色右邊對(duì)齊 X
距離藍(lán)色20 Y
first
item 紅色
relation
等于
second
item 藍(lán)色
constant
加上多少
multiplier
乘以多少
priority
優(yōu)先級(jí)
藍(lán)色:
距離頂部:20 Y
距離左邊:20 X
距離右邊:20 寬
高度: 50
紅色:
高度和藍(lán)色一樣 高度
紅色右邊和藍(lán)色右邊對(duì)齊 X
距離藍(lán)色20 Y
水平居中
圖片:
水平居中
垂直居中
距離左右為0
高度: 568 == 4inch
如果設(shè)置紅色View的寬度, 約束會(huì)自動(dòng)添加到紅色VIew中
如果是設(shè)置紅色View和綠色View的左邊距離固定,約束會(huì)自動(dòng)添加到綠色中(父子關(guān)系)
如果是設(shè)置紅色View和黑色View之間的距離固定, 約束會(huì)自動(dòng)添加到控制器的View上(兄弟)