1. 程式人生 > >iOS開發之AutoLayout中的Content Hugging Priority和 Content Compression Resistance Priority解析

iOS開發之AutoLayout中的Content Hugging Priority和 Content Compression Resistance Priority解析

本篇部落格的內容也不算太複雜,算是AutoLayout的一些高階的用法。本篇部落格我們主要通過一些示例來看一下AutoLayout中的Content Hugging Priority以及Content Compression Resistance Priority這兩個優先順序。下方我們先來簡單的看一下這兩個優先順序的涵義:

  • Content Hugging Priority:直譯成中文就是“內容擁抱優先順序”,從字面意思上來看就是兩個檢視,誰的“內容擁抱優先順序”高,誰就優先環繞其內容。稍後我們會根據一些示例進行介紹。
  • Content Compression Resistance Priority
    :該優先順序直譯成中文就是“內容壓縮阻力優先順序”。也就是檢視的“內容壓縮阻力優先順序”越大,那麼該檢視中的內容越難被壓縮。而該優先順序小的檢視,則內容優先被壓縮。稍後我們也會通過相應的例項來看一下這個優先順序的具體表現。

接下來我們就通過相應的例項來看一下這兩個優先順序的使用場景以及作用。

一、總述

首先在第一部分我們先來整體的看一下Content Hugging PriorityContent Compression Resistance Priority這兩個AutoLayout的優先順序屬性。這兩個屬性是可以在Storyboard中直接設定的,選中要設定的控制元件,在右邊約束一欄裡邊就有Content Hugging Priority

以及Content Compression Resistance Priority的設定地方。Content Hugging Priority的水平和豎直方向的預設值都是250,而Content Compression Resistance Priority的水平和豎直的預設值是750。我們可以在此對該值進行設定。

  

當然,在程式碼中也是可以設定這兩個程式碼的優先順序的。下方是使用程式碼的方式為我們的控制元件設定相應的優先順序並且我們可以獲取到相應優先順序的值。具體程式碼如下所示:

  

二、Content Hugging Priority

接下來我們就來結合例項來看一下Content Hugging Priority

的使用場景以及使用方式。

假如我們有一個需求,需要兩個Label並列顯示,我們暫且稱之為Label1Label2Label1Label2中的顯示內容是從網路獲取的,並且內容長度不定。我們要求優先顯示Label1。也就是說以Label1的寬度為準,不過Label1會有一個最大寬度,當Label1顯示到最大寬度時,Label1的內容會被壓縮,剩下的部分顯示Label2。當然,當Label1沒有顯示到最大值時,剩下的部分仍然顯示Label2。Label2顯示不全的也會被壓縮。

接下來我們按照上述的描述新增相應的約束,首先我們為Label1新增約束,如下所示。我們為Label1添加了Top、Left、Width和Height四個約束,這四個約束足以來確定該Label的位置了。不過需要注意的一點該Label的Width是小於等於某一個值得,此處我們指定的Width <= 200。也就是該Label的Width的最大值為200。約束新增後如下所示:

  

接下來我們來為並列第二個Label新增約束。因為要求前面Label內容顯示完成後,剩下的部分就顯示右邊Label的內容,所以我們為Label2添加了Left、Top、Right以及Height的約束。當然Left是以右邊的Label為基準的,而Right則是以父檢視為基準的。

  

從下方截圖中我們可以看出,有些約束新增完是紅色的,這就是約束有衝突了。也就是當前新增的約束不能確實當前控制元件的位置。從上述的約束我們不難發現,橫向來看,兩個Label的寬度都是不確定的,所以會報錯。

  

我們可以點選下方這個紅色的報錯箭頭檢視相應的報錯資訊。點選該紅色箭頭會顯示下方這個介面,該介面中會提示相應的錯誤資訊。從下面的對話方塊中我們可以看到具體的錯誤資訊是“Content Priority Ambiguity”,也就是說“內容優先順序是模稜兩可的”。點選這個紅色的圓圈,會給出相應的解決方案:

  • Decrease horizontal hugging of "Second Label" from 251 to 250 to make it grow before other views。

意思大體就是說:需要減小Second Label的水平擁抱優先順序,從現在的251換成250。換句話說,也就是將“Second Label”的Content Hugging Priority從251換成250後,下方的問題就會被解決了。“to make it grow before other views”,這句話的意思是降低這個優先順序目的是為了讓該檢視在其他檢視之前生長。

翻譯的有些晦澀,我們來用大白話說一下。造成下方錯誤的原因是水平放置的兩個Label的寬度都不確定,而且其內容環抱的優先順序又是一致的,所以在執行是我們無法確定是先確定第一個Label的寬度還是先確定第二個Label的寬度,解決方案是將右邊的Label的Content Hugging Priority的優先順序調低,當然第一個Label的Content Hugging Priority相對就高了。所以左邊的Label會優先的環繞其內容,也就是說該Label會優先的確定其寬度。當左邊Label的寬度確定了,那麼右邊Label的寬度也就是隨著確定了,所以下方的錯誤也就解決了。

  

下方就是我們將右邊的Label的Content Hugging Priority改成250後的結果。可以看出之前的報錯被解決了。當然,也可以將左邊的Label的Content Hugging Priority的優先順序修改成比右邊的高即可。此處我們僅討論了Content Hugging的水平方向上的優先順序,豎直方向上的優先順序是一樣的,在此就不做過多贅述了。

  

上面約束新增完以及優先順序新增完畢後,我們就可以看一下執行效果了。為了動態的看一下約束的效果,我們為每個Label添加了一個Step控制元件,從下方執行效果我們不難看出,該控制元件主要是用來控制對應Label的大小的。下方的執行效果是符合我們之前的預期的。左邊的Label的長度是有一個最大值得,當左邊的Label顯示完成後,右邊剩下的空間就顯示第二個Label的內容了。

  

三、Content Compression Resistance Priority (內容壓縮阻力優先順序)

聊完“內容擁抱優先順序”後,接下來我們就來看一下Content Compression Resistance Priority內容壓縮阻力優先順序,從字面意思上看,該優先順序越大則說明內容壓縮阻力越大,也就是說內容越難被壓縮。當兩個Label並排顯示,並且螢幕不足以顯示兩個Label的所有內容時,則會優先壓縮“內容壓縮阻力優先順序”越小則先被壓縮。

我們依然採用上一部分的方式,從錯誤入手,在錯誤解決的過程中來認識一下這個“Content Compression Resistance Priority”。首先我們也是讓兩個Label並排顯示,左邊的Label我們暫且稱之為FirstLabel,右邊的Label我們則稱之為SecondLabel。我們為FirstLabel新增的約束有Top、Left、Height以及Width >= 50,我們為SecondLabel新增的約束為Left(以First的Right為參照)、Top、Right、Height以及Width>=102。下方截圖就是我們新增上述約束後的效果:

  

新增完上述約束後,我們在Storyboard中可以看出是會報錯的。報錯原因也很明確“Content Priority Ambiguity”,也是內容優先順序衝突。用大白話解釋就是水平方向上無法確定兩個Label的寬度。當然點選紅色小圓點也會給出相應的錯誤解決方案:

  • Decrease horizontal compression resistance of "Bottom Label2" from 750 to 749 to make it get clipped before other views。

其大體意思就是減少第二個Label的水平壓縮阻力,將現在的750修改成749,使得SecondLabel在其他檢視之前被裁剪。此刻如果你點選該提示中的“Change Priority”按鍵的話,該錯誤將會被修復。

  

為了直觀的看一下該優先順序的效果,我們添加了一個Switch開關來修改上述兩個Label的優先順序。當Switch開關開啟時,FirstLabel的壓縮阻力優先順序大於SecondLabel,開關關閉就相反了。具體程式碼如下所示:
  

修改完相應的錯誤,以及新增完相應的程式碼後,接下來我們來看一下執行結果。當開關開啟時,前邊的抗壓縮阻力要大於後邊的Label。而開關關閉時後邊的抗阻力優先順序要大於前邊的,執行效果如下所示。

  

通過上述示例的演示,應該對Content Hugging Priority以及Content Compression Resistance Priority有了直觀的感受,本篇部落格就先到這兒吧。下方是上述示例在Github上的分享連結,如下所示: