基礎(chǔ) (十二) : Autolayout

適配

什么是適配?

適應(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)又是由像素組成的

像素越多,屏幕越清晰


未命名圖片.png

未命名圖片.png

什么是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è)核心概念

參照

約束

未命名圖片.png

未命名圖片.png

未命名圖片.png

未命名圖片.png

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

未命名圖片.png

未命名圖片1.png

未命名圖片2.png

未命名圖片3.png

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******************************

  1. 適配的歷史

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 最新的屏幕適配

  1. 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,

  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> 添加到爺爺身上

"添加約束到最大的控件上"
  1. 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)用者(控件)

  1. 優(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上(兄弟)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容