同時使用 IB 和 Masonry 時,如何刪除 NSIBPrototypingLayoutConstraint

爲何出現一種約束叫作 NSIBPrototypingLayoutConstraint

通常來說,約束的類型應該都是 NSLayoutConstraint,可是從 Xcode 4 開始,增長了 Auto Layout 功能時,考慮到當開發者在 IB 中建立 View 後,沒有顯示的主動添加任何約束,會致使視圖沒法顯示,所以 IB 會根據你拖動 View 的位置,自動的幫你加上約束,避免視圖沒法顯示,由於這種約束是 IB 自動添加的,所以類名叫 NSIBPrototypingLayoutConstraint,而且這種約束沒法經過 NSLog(@"%@", self.constraints); 打印出來。bash

深層次的緣由

通常來說,這種狀況下,對當前 View 設置ide

view.translatesAutoresizingMaskIntoConstraints = NO;
複製代碼

便可。工具

對於 translatesAutoresizingMaskIntoConstraints 屬性,官方文檔時這樣寫的:佈局

Discussion If this property’s value is YES, the system creates a set of constraints that duplicate the behavior specified by the view’s autoresizing mask. This also lets you modify the view’s size and location using the view’s frame, bounds, or center properties, allowing you to create a static, frame-based layout within Auto Layout.測試

Note that the autoresizing mask constraints fully specify the view’s size and position; therefore, you cannot add additional constraints to modify this size or position without introducing conflicts. If you want to use Auto Layout to dynamically calculate the size and position of your view, you must set this property to NO, and then provide a nonambiguous, nonconflicting set of constraints for the view.ui

By default, the property is set to YES for any view you programmatically create. If you add views in Interface Builder, the system automatically sets this property to NO.this

簡單翻譯一下,意思是說: 使用代碼建立 View 時,這個屬性默認是 YES,而後你就能夠經過設置其 frame、bounds、center 等屬性,自動的轉換爲 autoLayout 的約束。保證視圖約束的完整性,可以很好的顯示。spa

可是,你一旦這麼作了,那麼就不能額外給這個 View 添加約束了。由於,這個 View 已經有了 transfer 過來的約束,你再添加的話,約束將會衝突。翻譯

若是你但願可以手動地添加約束,來知足需求,那麼就須要設置 translatesAutoresizingMaskIntoConstraints = NOcode

在使用 IB 時,這個屬性默認是 NO。

一點疑惑 官方的說法中,在 IB 中,這個屬性應該是 NO,可是我經過 xib 建立的 UITableViewCell ,在 awakeFromNib 方法中,打印出該屬性是 YES。 就是由於這樣,才致使我在 awakeFromNib 方法中使用 masonry 添加的約束有了衝突。

解決問題的最終辦法

在 IB 中,顯示的爲 view 添加一些約束,而後所有選擇這些約束,在 File Inspector 中,勾選 Remove at build time;



example-1.png

爲何上述方法能夠解決問題

問題的根本是 IB 自動建立了咱們不想要的約束,IB 自動建立的緣由是 view 上沒有約束,所以咱們隨意給 view 添加一些無用的約束,而後讓其在 building 時刪除掉。 這樣子,當代碼執行到 masonry make 建立約束時,這個 view 將是一個乾淨的 view。

Placeholder : Remove At build time

這個屬性呢,其實原本的使用場景是這樣: 在開發過程當中,有時候須要預覽一些佈局,那麼在 Storyboard 上添加約束,就會很方便,這樣子在不執行代碼的狀況下,就可以測試驗證咱們的約束是否正確。

可是呢,在實際開發中,極可能你們以爲在 storyboard 上添加約束比較麻煩,團隊之間協做很差,所以但願可以使用代碼建立約束,好比 masonry 這種工具。

很簡單,只須要在運行時,將 storyboard 中添加的約束所有刪除掉。這樣子,storyboard 中添加的約束不會對代碼添加的約束形成任何影響。另外一方面,在 storyboard 中佈局能夠更加方便,且 storyboard 中不會出現一堆關於約束的 warning。

後記

有什麼問題,能夠留言,我會盡快回復~

相關文章
相關標籤/搜索