屏幕適配—約束的添加

我們知道,現(xiàn)在已經不像以前那樣只有一個尺寸,現(xiàn)在最少的iPhone開發(fā)需要最少需要適配三個以上尺寸。因此以前我們可以使用硬坐標去設定各個控件的位置,但是現(xiàn)在的話已經不可以了,我們需要去做適配,也許你說可以使用兩套UI或兩套以上的UI,但那樣不高效也不符合設計。iOS有兩大自動布局利器:autoresizing和autolayout(autolayout是IOS6以后新增)。autoresizing是UIView的屬性,一直存在,使用也比較簡單,但是沒有autolayout那樣強大。如果你的界面比較簡單,要求的細節(jié)沒有那么高,那么你完全可以使用autoresizing去進行自動布局。也就意味著,現(xiàn)在,做IOS開發(fā),屏幕適配是必須考慮的問題,而實現(xiàn)屏幕的適配的主要方式就是autolayout,而使用autolayout的關鍵步驟就是為控件添加相應的約束,

下面,我們就對約束的添加做一些說明。

一:通過系統(tǒng)提供的面板實現(xiàn)約束的添加

現(xiàn)在IOS6以上,系統(tǒng)會自動選擇使用autolayout,在“show the file

inspector”面板中可以找到這個屬性:

,如果選擇了這個屬性,那么在編輯區(qū)域的右下方就可以看到一些有關autolayout的選項了:

首先,我們對對autolayout主要使用選項做一些說明,其實常用的主要是三個選項:

1.Align面板:

2.Pin面板:

細節(jié)說明:constraint to margin:選項的作用。這個屬性是IOS8才添加的,它默認會在屏幕左右添加8個點的邊距,也就意味著參考不是從屏幕邊緣0的位置開始的,而是從8個點的位置開始的。一般來說,對于直接參考屏幕的控件,可以選擇這個選項,如果是對于子控件,就沒有必要選擇了。

3.Resolve面板:

之后,我們介紹一下約束的添加方式。說白了,所謂的約束的本質就是為控件設置好frame屬性值,只不過它添加了參照,而不像frame屬性一樣,只是針對控件本身。所謂參照就是它可以在其它控件或者父容器(如屏幕)有變化的時候,讓自身的frame也產生合理的變化。下面以一個簡單案例來說明一下約束的添加:

1.案例結果圖:

2.添加相應的view控件,選擇Pin面板,添加左和上的約束:

注意,不要選擇更新約束,因為,如果約束不能正確的得到控件的frame屬性,那么系統(tǒng)將很有可能不能正確的繪制出控件,只有當frame有四個屬性(size(width.height),origin:(x,y))都能通過約束正確的計算出來才能更新約束。

3,設置寬高,我們需要view的寬度和高度都是屏幕的一半,但是,通過寬高屬性卻不能進行設置,否則就是固定寬高數(shù)值,以后不能進行屏幕的自動適配了。這個時候,面板就不夠用,我們還需要使用到約束的修改屬性面板,具體實現(xiàn)如下:

3.1先為view添加與屏幕右和下邊距為0--view會填充整個屏幕

3.2找到約束,選擇想修改的約束,我們想修改view與屏幕右和下的約束關系,那就一個一個選擇這些約束進行修改,例如我們先選擇右邊距約束:

然后,查看約束的具體的屬性:

那么一切都一目了然了。根據(jù)里面的序號讀一遍就可以得到約束這個結果:紅色view的最右邊等于父容器的最右邊數(shù)值乘以1加上0,很明顯,就是紅色view的最右邊與父容器的最右邊對齊,也就是等寬。所以根據(jù)示例結果,只需要將Multiplier修改為0.5,紅色view的寬度就是父容器寬度的一半了,對于高度也是同樣的處理方式。

說到這里,就不得不說一下在sb中還有一種方面的添加約束的方式:拖線。還是上面那個案例,剛才我們是通過添加四個方向的邊距約束(特別是右,下)達到紅色view的寬高和高度為父容器的一半,我們也可以通過直接設置紅色view的寬高和父容器的寬高之間的關系來達到同樣的效果。

1.拖線:

2.這里需要說明的是,拖線的方向決定了顯示出的菜單項,如果往左下方向拖線,那么就可以看到添加當前控件與父容器左邊距和底邊距的選項。其它方向的拖線一樣的道理。這里我們選擇等寬等高(按住shift鍵可以同時添加多個約束):

添加后的約束列表:

3.修改添加了等寬等高約束:

讀出來就是這樣的:blueView的寬度等于父容器的寬度乘以0.5加上0,也就是寬度為父容器寬度一半。

其它幾個view的制作方式基本一樣啦。

二:通過代碼實現(xiàn)約束的添加

代碼添加約束其實就是將約束的屬性面板所表達的含義使用代碼進行描述,官方文檔中,它的基本公式為:

意思是:第一個item的屬性=(所參照的item的屬性*倍數(shù))+常量值。

1.添加約束的類: NSLayoutConstraint

2.添加約束的常用方法:

[NSLayoutConstraint

constraintWithItem:<#(第一個item)#> attribute:<#(某個屬性)#> relatedBy:<#(屬性與屬性之間的關系)#> toItem:<#(參照的item)#> attribute:<#(被參照item的指定屬性)#> multiplier:<#(倍數(shù))#> constant:<#(增加的常量)#>];

3.參數(shù)的一些說明:

3.1.NSLayoutRelation:這是一個枚舉,說明了屬性之間的關系,需要注意的是,如果關系設置為等于,但是后期因為某些原因造成屬性值不再是等于,則系統(tǒng)會給出相應的警告。

NSLayoutRelationLessThanOrEqual = -1,---小于等于

NSLayoutRelationEqual = 0,---等于

NSLayoutRelationGreaterThanOrEqual = 1, --大于等于

3.2. NSLayoutAttribute:item的屬性:

NSLayoutAttributeLeft = 1,左

NSLayoutAttributeRight,右

NSLayoutAttributeTop,頂

NSLayoutAttributeBottom,底

NSLayoutAttributeLeading,左

NSLayoutAttributeTrailing,右

NSLayoutAttributeWidth,寬

NSLayoutAttributeHeight,高

NSLayoutAttributeCenterX,水平中心

NSLayoutAttributeCenterY,垂直中心

NSLayoutAttributeBaseline,基線

NSLayoutAttributeLastBaseline = NSLayoutAttributeBaseline,相當于,兩者等價

------------下面是ios8之后的如果想添加默認邊距的屬性列表--------------

NSLayoutAttributeFirstBaseline NS_ENUM_AVAILABLE_IOS(8_0),

NSLayoutAttributeLeftMargin NS_ENUM_AVAILABLE_IOS(8_0),

NSLayoutAttributeRightMargin NS_ENUM_AVAILABLE_IOS(8_0),

NSLayoutAttributeTopMarginNS_ENUM_AVAILABLE_IOS(8_0),

NSLayoutAttributeBottomMargin NS_ENUM_AVAILABLE_IOS(8_0),

NSLayoutAttributeLeadingMargin NS_ENUM_AVAILABLE_IOS(8_0),

NSLayoutAttributeTrailingMargin NS_ENUM_AVAILABLE_IOS(8_0),

NSLayoutAttributeCenterXWithinMarginsNS_ENUM_AVAILABLE_IOS(8_0),

NSLayoutAttributeCenterYWithinMargins NS_ENUM_AVAILABLE_IOS(8_0),

NSLayoutAttributeNotAnAttribute = 0這不是一個屬性,如果一個item的約束不需要參照其它的item,那么就使用這個。

說明:NSLayoutAttributeLeft| NSLayoutAttributeLeading,NSLayoutAttributeRight| NSLayoutAttributeTrailing的區(qū)別:

NSLayoutAttributeLeft和NSLayoutAttributeRight代表從左到右進行布局,NSLayoutAttributeLeading和NSLayoutAttributeTrailing代表從前到后進行布局,在我國NSLayoutAttributeLeft和NSLayoutAttributeLeading是一個效果的,布局習慣從左到右,但在有些國家地區(qū)(如中東地區(qū)等),布局習慣從右往左。那么NSLayoutAttributeRight反而和NSLayoutAttributeLeading是一個效果了,為了避免這些地區(qū)的問題,我們推薦使用:NSLayoutAttributeLeading和NSLayoutAttributeTrailing(比較安全和常用)

4.使用代碼實現(xiàn)剛才的案例示例:

4.1一定要去除autoresizing屬性

4.2創(chuàng)建約束

4.3根據(jù)約束添加規(guī)則添加約束到控件或者父容器

4.4代碼:

-(void)viewDidLoad {

[superviewDidLoad];

//去除autoresizing屬性

self.redView.translatesAutoresizingMaskIntoConstraints=NO;

self.view.translatesAutoresizingMaskIntoConstraints=NO;

//添加頂部約束

NSLayoutConstraint*constraintT=[NSLayoutConstraintconstraintWithItem:self.redViewattribute:NSLayoutAttributeToprelatedBy:NSLayoutRelationEqualtoItem:self.redView.superviewattribute:NSLayoutAttributeTop multiplier:1constant:0];

//添加左邊約束

NSLayoutConstraint*constraintL=[NSLayoutConstraintconstraintWithItem:self.redViewattribute:NSLayoutAttributeLeftrelatedBy:NSLayoutRelationEqualtoItem:self.redView.superviewattribute:NSLayoutAttributeLeft multiplier:1constant:0];

//添加寬度約束

NSLayoutConstraint*constraintW=[NSLayoutConstraintconstraintWithItem:self.redViewattribute:NSLayoutAttributeWidthrelatedBy:NSLayoutRelationEqualtoItem:self.redView.superviewattribute:NSLayoutAttributeWidth multiplier:0.5constant:0];

////添加高度約束

NSLayoutConstraint*constraintH=[NSLayoutConstraintconstraintWithItem:self.redViewattribute:NSLayoutAttributeHeightrelatedBy:NSLayoutRelationEqualtoItem:self.redView.superviewattribute:NSLayoutAttributeHeight multiplier:0.5constant:0];

//添加約束到控件--根據(jù)規(guī)則,添加到父容器

[self.redView.superview addConstraints:@[constraintT,constraintL,constraintW,constraintH]];

}

蘋果還提供一種添加約束的VFL語言,有興趣的也可以去看一下相關的文檔說明。

當然,以后在進行開發(fā)過程中,效率至上,一般會使用第三個框架。如常用的框架有Masonry,一般第三方框架找到框架的幫助文檔就能方便的學習和使用了。

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

相關閱讀更多精彩內容

友情鏈接更多精彩內容