日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Auto Layout 和 Constraints

發布時間:2023/11/29 编程问答 56 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Auto Layout 和 Constraints 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章修改
2月1日:添加使用約束、編輯約束和iOS特性三個部分
2月24日:根據自己的理解,修改iOS特性部分的內容

自動布局Auto Layout

Auto Layout,通過設置在View上的約束,動態計算視圖層次結構中所有的View的尺寸和位置。舉個栗子,你約束一個Button,令它的水平中心線和一個ImageView相同,并且它的上邊緣距離ImageView的下邊緣有8個像素。如果ImageView的尺寸或者位置改變,Button會自動調整,以符合之前設置的約束。

基于約束的Auto Layout,使我們搭建能夠動態響應內部和外部變化的用戶界面。

外部變化

外部變化發生于superview的尺寸或者位置改變,比如,

  • 設備屏幕旋轉;

  • 支持不同屏幕大小的設備。

這時,所有的View都要重新計算尺寸和位置。每一次變化,都會刷新視圖層級結構的布局。這些變化大部分發生在運行時,它們需要APP能夠動態響應。

內部變化

內部變化發生于你的界面中的View的尺寸或者位置發生改變。比如,

  • APP中顯示的內容的改變,新的內容可能需要一個新的布局。一般,在顯示文字或者圖片時會出現這種情況;

  • APP支持動態設置。如果用戶可以設置字體大小,這將會改變任何與文本相關的控件的高度或者寬度,布局必須能夠適應變化。

約束Constraints

Auto Layout的實現是基于設置在View上的一系列約束的。每一條約束都是一個表達式。

下圖是官方文檔給的示例圖:

這個約束表明,Red View的左邊緣與Blud View的右邊緣的距離為8。這個等式由以下幾個部分組成:

  • Item 1 :表達式中的第一個控件。在這個例子中是Red View;

  • Attribute 1 :第一個控件的一個屬性。在這個例子中是Red View的leading edge;

  • Relationship :表達式左右兩邊的關系,可以使等于,大于等于或者小于等于。在這個例子中,兩邊的關系是相等的;

  • Multiplier :和第二個控件的屬性相乘的乘數,是一個浮點型。在這個例子中是1.0。一般情況下,這個值不可置為0.0;

  • Item 2 :表達式中的第二個控件。在這個例子中是Blue View。它是可以為空的,即表達式變成Item 1 * Attribute 1 = 0.0 * NotAnAttribute + Constant;

  • Attribute 2 :第二個控件的一個屬性。在這個例子中是Blue View的trailing edge;

  • Constant :一個浮點型的常數。在這個例子中是8.0。

大部分的約束是定義兩個控件之間的關系。這些控件必須是View或者是Layout Guide。約束也可以定義一個控件的兩個屬性之間的關系,比如設置一個控件的上邊緣到下邊緣的距離、左邊緣到右邊緣的距離,即它的高度或者寬度。當表達式中的Item 2為空時,它的屬性必須被設為Not An Attribute,并且Multiplier置為0.0。

約束中用到的屬性

通常情況下,包含四個邊(leading,trailing,top和bottom),以及高度(height),寬度(width),水平中心點(CenterY),垂直中心點(CenterX)。文本類型的控件還有一個基線(baseline)屬性。

屬性說明

  • Height和Width。這兩個屬性可以被直接賦值,可以是一個常數,也可以是其他View的Height或者Width值。但是,不可以為負數。

  • Top、Bottom、Baseline。可以和Top、Bottom、Baseline、CenterY組合。

  • Leading和Trailing。可以和Leading、Trailing、CenterX組合。

  • Left和Right。避免使用這兩個屬性,而使用Leading和Trailing來替代它們。

  • CenterX和CenterY。CenterX可以和Leading、Trailing、Left、Right組合。CenterY可以和Top、Bottom、Baseline組合。

使用屬性定義約束

上面提到的屬性可以分為兩類,尺寸相關和位置相關。尺寸相關(如height、width)用來定義物件的大小。位置相關(如leading,top)的屬性用來表明該物件和其他物件之間的位置關系。使用這些屬性時需要注意:

  • 不要使用尺寸相關的屬性去約束一個位置相關的屬性。

  • 只可以給尺寸相關的屬性直接賦值一個常量。

舉幾個簡單的例子:

// 設置一個固定高度 View.height = 0.0 * NotAnAttribute + 40.0// 設置兩個按鈕之間的固定距離 Button_2.leading = 1.0 * Button_1.trailing + 8.0// 讓兩個按鈕的左邊緣對齊 Button_1.leading = 1.0 * Button_2.leading + 0.0// 給兩個按鈕相同的寬度 Button_1.width = 1.0 * Button_2.width + 0.0// 讓View的中心和父類的中心相同 View.centerX = 1.0 * Superview.centerX + 0.0 View.centerY = 1.0 * Superview.centerY + 0.0// 設置一個View的寬高比 View.height = 2.0 * View.width + 0.0

約束的設置沒有最好的,只有最適合的。

約束的優先級

優先級priority是Auto Layout在計算的時候用到的參數。優先級的值可以是1-1000任意整數。系統定義了low(250)、medium(500)、high(750)和required(1000)四個等級。一般情況下,我們手動設置的優先級的值也會集中在這四個等級下。

優先級默認值是1000。

關于Auto Layout是如何通過優先級來計算出解決方案,我在看完官方文檔后還是一頭霧水。希望有大神可以指點一二。

使用約束

添加約束

在storyboard中有3種方式添加約束。

  • 在View之間使用Control-Drag;

  • 使用Pin和Align工具;

  • 讓Interface Builder自動添加約束。

Control-Dragging

所謂Control-Draging就是按住Control鍵,用鼠標左鍵拖動的方式添加約束。這兩步操作也可以用按住鼠標右鍵拖動來替代。

當釋放鼠標左鍵后,就會彈出一個HUD,顯示可以設置的約束。

Interface Builder會根據選擇的兩個控件以及拖動的方向篩選出可以設置的約束。如果拖動的方向傾向于水平,你可以選擇設置水平方向上的間距和垂直方向上的對齊方式。反之,如果拖動的方向傾向與垂直,則可以選擇設置垂直方向上的間距和水平方向上的對齊方式。

提示:

  • 可以從一個控件拖動到另一個控件,設置它們之間的關系。也可以拖動到控件自身,設置寬度和高度;

  • 不僅可以在Scene中直接拖動,可以在Storyboard左側的視圖大綱中用同樣的方式拖動。在大綱中拖動設置約束,會顯示出所有的可選約束,而不會進行篩選;

  • Control-Dragging可以非常快速得設置約束。這些約束是基于Scene中View的當前的位置,因此在設置約束之前要定位好View。

  • 使用Stack、Align、Pin、Resolve工具

    Interface Builder在Storyboard的編輯窗口的右下角提供四個自動布局的工具,分別是Stack、Align、Pin、Resolve Auto Layout Issues。

    當你想精確控制約束的Constant或者想一次性添加多個約束,可以使用Align和Pin工具。使用Align和Pin還有一個好處,我們不是必須要設置好View的位置,而是只需要定好相對位置,添加約束,然后update frames。Auto Layout會自動計算出正確的位置。

    Stack Tools

    Stack Tools可以將選中的一個或者多個控件嵌入到一個Stack View中,并會重新計算布局。Stack View是iOS 9添加的新特性。

    對于Stack View,我還沒有弄明白使用方法,所以這里不講述。

    Align Tool

    Align Tools可以快速對齊控件。選擇一個或多個你想對齊的控件,然后單擊Align Tool。然后會彈出可選的一系列對齊方式。

    選擇其中的選項,然后點擊Add Constraints。之后,就會自動添加對齊的約束設置。大部分情況下,會選擇兩個或者兩個以上的View來設置對齊。Horizonally in Container和Vertically in Container這兩個可以添加到單一的View上。

    Pin Tool

    Pin是大頭針的意思。所以這個工具可以用來給View定位。它可以讓我們快速設置一個View相對于它周邊View位置或者它的寬高。選擇一個你想對其進行定位的View,單擊Pin Tool,會彈出如下的窗口。

    窗口的上半部分,可以設置選中的View的Top,Bottom,Leading,Trailing與相鄰最近的View的間距。最初顯示的數字是當前的間距。我們可以輸入一個自定義的值,還可以點擊輸入框右邊的倒三角,在彈出的下拉菜單中選擇參照的View。關于Constrain to margins選項,如果選中,會將父視圖的外邊距作為間距的值的參考。

    下半部分可以設置寬高相關的屬性。寬和高默認的是Scene中的尺寸,也可以自定義值。寬高比的默認值也是根據Scene中的尺寸進行計算。如果想自定義的話,只有在設置完寬高比之后修改這個約束。

    一般情況下,選擇一個View,對它進行定位。選擇兩個及其以上的View設置Equal Height或者Equal Width。使用Pin Tool設置完約束后,可能需要Update frames。

    Resolve Auto Layout Issues

    Resolve Auto Layout Issues提供一些解決Auto Layout問題的方法。上半部分只針對選中的View,下半部分則針對Scene中所有的View。

    我們可以

    • 根據當前約束更改frame;

    • 根據當前frame更改約束的設置;

    • 添加缺少的約束;

    • 清除已添加的約束;

    • 設置系統推薦的約束。

    這些功能字面上寫得很清楚,具體的效果大家可以用簡單的Demo來看一下。

    讓Interface Builder為我們設置約束

    Interface Builder可以為我們創建部分或者全部的約束。根據所提供的View的尺寸和位置,它會推斷出最好的約束。前提是,我們必須確定View的位置并不再更改。一個小小的間距的改變,可能對于整個布局來說確實巨大的。

    如果想讓Interface Builder來完成約束的添加,單擊上文提到的Resolve Auoto Layout Issues工具,點擊Reset to Suggested Constraints。Interface Builder就會為已選的(也可以是Scene中全部的)View創建合適的約束。

    另外,我們可以自己添加一部分約束,然后選擇Add missing Constraints,讓Interface Builder來添加剩下的所需的約束。

    這種方法可以快速完成約束的設置。但是,有可能運行得到的UI并不是你想要的。要不斷地測試UI,修改約束,以達到最終想要的效果。

    編輯約束

    添加約束之后,需要能夠找到它、查看它、編輯它。

    在Scene里查看約束

    編輯窗口會顯示作用于當前選擇的View的約束。通過線的形狀、顏色和類型說明當前約束的當前狀態。

    • I-bars(兩端是T型的線):I-bars顯示間距的大小。可能是兩個控件之間的大小,可能是一個控件的高度或者寬度。

    • Plain Line(一條普通的直線):Plain Line顯示控件邊緣的對齊方式。例如,兩個或兩個以后的控件是左對齊的,那么,這條線會連接著這些控件,并且與它們的Leading之間的間距為0。

    • Solid Line:實線表示這個約束是Required,即priority == 1000。

    • Dash Line:虛線表示這個約束是Optional,即priority < 1000。

    • Red Line:紅線表示被約束的影響的控件的約束設置有錯誤。具體的原因可以點擊大綱中每個Scene的右邊的箭頭查看。這時,箭頭是紅色的。

    • Orange Line:橘黃色的線表明,Auto Layout根據已有約束計算出來的frame和當前Scene中設置的frame不同。這時,大綱中的右邊的箭頭是黃色的。可以用Resolve Auot Layout Issues -> Update frames來進行修正位置。

    • Blue Line:藍色的線表示當前的約束設置是正確的,并且控件的位置和Auto Layout計算出來的位置是一樣的。

    • Equal Badges:相等標記表明兩個控件的寬度或者高度是相同的。并且標記中包含=符號。

    • Greater-than-or-equal and less-than-or-equal badges:和Equal Badges類似,它們是標記約束的關系是大于等于或者小于等于的,同時也會顯示對應的符號。

    快速找到并編輯添加的約束

    所有添加的約束都陳列在大綱里。這些約束以偽代碼的形式呈現。當選擇一個約束時,會在Scene中高亮顯示,可以幫助我們快速找到它。而且,可以在右側的Show the Size inspector下對約束的Constant、Priority、Multiplier、Relation、Identifier、Placeholder屬性進行編輯。

    一旦UI變得復雜之后,我們用這種方式找約束就會顯得很吃力。Show the Size inspector工具可以顯示出在當前選中的控件上添加的約束。約束的一部分屬性也可以在這里進行修改。

    注意:這里雖然都是在Show the Size Inspector下進行修改,但是前者是選擇一個約束,后者是選擇一個控件。

    Auto Layout在iOS中的特性

    iOS在與Auto Layout方面有一些獨有的特性,包括top and bottom layout guides、Layout Margins。

    Top and Bottom Layout Guides

    top and bottom layout guides表示當前的ViewController從最上面到最下面的可見范圍。如果不希望顯示的內容在UIKit bars(例如status bar,navigation bar,tab bar)下面,那么就可以和上下的layout guide來設置約束。

    layout guides是遵守UILayoutSupport協議的。這個協議有一個length屬性,來表示guide和root view(root view就是ViewController默認添加的view)邊緣的距離:

    • 對于top layout guide,length指明ViewController的root view的上邊緣和覆蓋在root view上的bar(例如status bar和navigation bar)的底部的距離。

    • 對于bottom layout guide,length指明ViewController的root view的下邊緣和覆蓋在root view上的bar(例如tab bar)的頂部的距離。

    在iOS 9中,guide也可以像控件一樣,支持用top、bottom、height設置約束。比如,用top layout guide的bottom屬性和bottom layout guide的top屬性與view設置約束。UILayoutSupport還提供了topAnchor、bottomAnchor、heightAnchor屬性,可以讓我們用代碼的形式來設置約束。

    如果layout guides是view最近的"控件",那么系統會自動將layout guides作為設置約束的對象。當使用Pin Tool時,可以在layout guides和root view的上下邊緣進行選擇。

    Layout margins

    Auto Layout為每一個view都定義了margin。margin指的是控件顯示內容部分的邊緣和控件邊緣的距離。就像“回”這個漢字一樣,外面的“口”就是控件的外邊緣,里面的“口”是控件顯示內容的部分的邊緣,我暫且稱它為內邊緣,這兩個邊緣之間的距離就是margin。

    可以用layoutMargins或者layoutMarginsGuide屬性獲得view的margin。layoutMargins允許獲取或者設置UIEdgeInsets結構的margin,layoutMarginsGuide則只會獲取到只讀的UILayoutGuide對象。

    每一個view的默認的margin是8。可以根據APP的需要進行修改。__系統給ViewController的root View設置的margin則不能修改__。root View的上下的margin為0,左右的margin為20。

    當使用Control-Dragging方式,給一個View和它們父視圖設置約束時,默認使用內邊緣,而不是外邊緣。當使用Pin Tool時,如果Constraint to margins被勾選,則會使用父視圖的內邊緣作為設置約束的參照,如果沒有被勾選,則使用外邊緣作為設置約束的參照。所見到的效果就是兩種參照下的約束的Constant的值相差一個margin。

    當在Interface Builder中編輯約束時,First Item和Second Item的彈出菜單中可以選擇Relative to margin。如果勾選,會在top、leading等屬性后面加上Margin,變成topMargin、leadingMargin等,意味著約束的設置參照View的內邊緣而不是外邊緣。

    設置約束時的一些建議

    官方文檔為我們提供了一些設置約束時的建議

    • __在最相近的兩個控件之間創建約束。__假如有3個Button,分別是first,second,third。可以約束first的右邊緣和second的左邊緣的距離,second的右邊緣和third的左邊緣的距離。而不要約束first的右邊緣和third的左邊緣距離,中間隔了一個second。

    • __避免設置固定的高度和寬度。__Auto Layout是動態響應布局的變化。一個控件如果設置固定尺寸,那么就會失去自動調整的能力。

    • 在update frames時注意,如果這個控件沒有設置足夠多的約束來確定它的位置和尺寸,那么可能會導致一些意想不到的后果。比如會跑到屏幕外,或者因為寬度、高度為0而消失等等。

    • 給所有的控件取一個有意義的名稱。在使用工具時,可以方便地辨別出View。

    • 使用leading和trailing代替left和right。

    • 當使用代碼創建約束時,確保將它們的translatesAutoresizingMaskIntoConstraints屬性為NO。默認情況下,系統會基于控件的frame自動創建一系列約束。當你添加自己的約束時,不可避免地會和自動生成的約束產生沖突。

    參考內容:
    蘋果官方文檔:Auto Layout Guide

    本文中的圖片均取自蘋果官方文檔

    總結

    以上是生活随笔為你收集整理的Auto Layout 和 Constraints的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。