2014-01-13 41 views
13

我使用的自動佈局約束編程和我經常看到相同類型的錯誤在我的應用程序通常與看起來像這樣的約束:自動版式約束問題突發NSAutoresizingMaskLayoutConstraint

"<NSAutoresizingMaskLayoutConstraint:0x82da910 h=--& v=--& V:[UITableViewCellContentView:0x82d9fb0(99)]>" 

我已經把一些樣本代碼重現在https://github.com/nicolasccit/AutoLayoutCellWarning

在本例中,我建立與2個UI元素一個非常簡單的視圖:稱爲imageThumbnail的圖像視圖和被叫標籤與一些約束標籤:

"H:|-padding-[_imageThumbnail(==imageWidth)]-[_labelName]"; 
"V:|-padding-[_imageThumbnail(==imageHeight)]-padding-|"; 
"V:|-padding-[_labelName]"; 

在這兩個元素上,我將AutoresizingMaskIntoConstraints設置爲NO。

而且我得到以下異常:

Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSLayoutConstraint:0xa6e4f90 V:[UIImageView:0xa6e4340]-(10)-| (Names: '|':UITableViewCellContentView:0xa6e4150)>", 
    "<NSLayoutConstraint:0xa6e4f10 V:[UIImageView:0xa6e4340(80)]>", 
    "<NSLayoutConstraint:0xa6e4ed0 V:|-(10)-[UIImageView:0xa6e4340] (Names: '|':UITableViewCellContentView:0xa6e4150)>", 
    "<NSAutoresizingMaskLayoutConstraint:0xa6e4ac0 h=--& v=--& V:[UITableViewCellContentView:0xa6e4150(99)]>" 
) 

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0xa6e4f90 V:[UIImageView:0xa6e4340]-(10)-| (Names: '|':UITableViewCellContentView:0xa6e4150)> 

我知道最後的約束相關內容的看法,但我不清楚正確刪除它(設置
AutoresizingMaskIntoConstraints爲NO的內容查看引發誤差和下方的SO鏈接,它打亂了整個佈局):

<NSAutoresizingMaskLayoutConstraint:0xa6e4ac0 h=--& v=--& V:[UITableViewCellContentView:0xa6e4150(99)]> 

我在看到了答案:Auto layout constraints issue on iOS7 in UITableViewCell但他們都不在這裏爲我工作。

我相信我定義的約束條件是有效且相當直接的,但似乎無法弄清楚發生了什麼。我看到在iOS 6.1和iOS 7中都出現異常。

任何想法我在這裏做錯了嗎?

感謝, 薩科

回答

5

我已將您的代碼的更正版本放在https://github.com/mattneub/AutoLayoutCellWarning。完美的作品。這條線是你麻煩的主要原因:

NSString *const kImageVertical = @"V:|-padding-[_imageThumbnail(==imageHeight)]-padding-|"; 

改變,要

NSString *const kImageVertical = @"V:|-padding-[_imageThumbnail]-padding-|"; 

而且一切都會好起來。

您遇到麻煩的主要原因是,通過爲圖像視圖指定絕對高度,您無法爲單元格指定高度。浮點不精確,因此您需要爲單元格增加/縮小留出一些空間。如果我們拿走絕對高度,圖像視圖會從內在內容大小中獲取高度,但優先級較低,因此不存在衝突。

我對你的代碼有一些其他的批評。在嘗試使用自動佈局進行單元格高度的動態設置時,您正在給出您不應該給予的佈局和約束更新命令,並且您在錯誤的時間給它們。可以根據約束來實現動態行高,但是你做這件事的方式不是這樣。您只需撥打systemLayoutSizeFittingSize即可找出正確的細胞高度。此外,絕對不需要將「隱藏」單元放入界面。不要那樣做;它只是混淆了事情。當您查看我的代碼版本時,您會注意到的一件事是,由於這些差異,它比您的代碼更簡單。

對於一個工作方法,請參閱我的例子在https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/bk2ch08p424variableHeights/ch21p722variableHeights/RootViewController.m

而且看到這個問題in my book的討論。

編輯(2014年5月):不幸的是我的回答上面的失敗指出的這個問題,即關鍵原因之一,該細胞分離機具有高度(如果它沒有被設置爲無) 。因此,如果您將單元格的高度考慮爲不考慮分隔符高度,則自動佈局約束(如果是絕對的)無法解析爲該高度。 (見this answer,真的讓燈泡進來我的頭。)

+0

有趣。如果我試試這個,我得到以下異常:「***終止應用程序由於未捕獲的異常‘NSInternalInconsistencyException’,理由是:‘自動佈局仍在執行-layoutSubviews後需要TableViewCell的實現-layoutSubviews的需要調用超。’」你是否在行後面添加它:「if(self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]){」? – nicolasccit

+0

嗨馬特,我一直在努力遵循這一設置我的約束和佈局命令:http://stackoverflow.com/questions/18746929/using-auto-layout-in-uitableview-for-dynamic-cell-layouts-可變行高度 對於簡單的情況下,我在GitHub上,我並不真的需要靈活的細胞高度,但我在多行標籤真實的案例做。你介意澄清我做錯了什麼?基本上,爲什麼我應該「永遠不要給」這些命令或「在錯誤的時間給他們」? – nicolasccit

+0

我嘗試刪除約束上的填充並刪除警告,正如你所說現在的行高是問題。 我可以在這個例子中手動設置高度,但在我的實際使用中,不同的單元格會有不同的高度。 從概念上講,在這個非常簡單的例子中,我想說: - 圖像應該是從頂部10pt和底部10pt和80pt高。 - 單元格的高度應該在viewController中自動計算。 爲此,我只創建一個隱藏單元,其目的就是爲了實現這一點。 – nicolasccit

6

你應該更加仔細閱讀異常說明:

Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints 

總之,這種限制,你看到的是,由於一些的UIView有它translatesAutoresizingMaskIntoConstraints設置爲YES。在這種情況下,我會懷疑這是單元格的內容視圖,如UITableViewCellContentView暗示的那樣。

只需將屬性設置爲NO即可將其禁用。

cell.contentView.translatesAutoresizingMaskIntoConstraints = NO 

編輯: 現在,請記住,這是一個臨時的解決辦法,最有可能你有你的約束其他一些邏輯錯誤,例如限制在細胞到細胞自身的contentView東西。或者看似強迫contentView比單元大(因此大於其自動調整大小)。

例如,你的手機夠高嗎?即它是否足夠高以至於contentView是100pt高?請注意,contentView必須高,這可能不一定匹配單元格的高度。

+0

謝謝你的答案,但我不相信這是正確的。我不相信你應該在contentView上設置autoResizingMaskIntoConstraints。 首先,在我鏈接到的SO問題中,解釋如下:「我無法將contentView的translatesAutoresizingMaskIntoConstraints屬性設置爲NO =>它會弄亂整個單元格。」在我的情況下,如果我嘗試,我會得到以下異常:「由於未捕獲的異常」NSInternalInconsistencyException「而終止應用程序。除非有其他的東西我錯過了。 – nicolasccit

+0

這可能有助於後一個例外。 http://stackoverflow.com/questions/12610783/auto-layout-still-required-after-executing-layoutsubviews-with-uitableviewcel但是,是的,理想情況下,你不需要操縱該屬性,在你的情況下,你顯然有一個邏輯錯誤的佈局大小... 例如,擺脫圖像的高度限制,並在佈局完成後註銷它的框架,我懷疑它不會是80pt(意味着沒有足夠的空間來實現你想要的佈局)。 –

+0

如果我刪除圖像上的高度約束,則異常消失,幀高變爲23.0。雖然用戶界面與我擁有約束時相同。當我讓約束和打印圖像的幀高時,它是80.0。 – nicolasccit