2014-11-21 116 views
4

我有UITableView與動態高度UITableViewCell s和我正在使用自動佈局來計算高度根據主題this excellent answer。到現在爲止還挺好。自動佈局與相對約束不影響systemLayoutSizeFittingSize:對於UITableViewCell

我正在調整應用程序以適應較大的iPhone(6和6 Plus)屏幕尺寸,它大多非常簡單。

但是,在我的一些單元格中,我想要跨越整個單元格寬度的圖像,並且我希望圖像的高度與圖像的寬度成比例(0.55 *寬度具體)。到目前爲止,我已經在自動佈局約束條件下硬編碼圖像的寬度和高度,基於iPhone 6/6 Plus之前的標準320px縱向桌面視圖寬度。

我認爲這將是簡單的添加一個相對高度的限制,像這樣(我使用PureLayout):

[self.myImage autoMatchDimension:ALDimensionHeight 
        toDimension:ALDimensionWidth 
          ofView:self 
        withMultiplier:0.55f 
         relation:NSLayoutRelationGreaterThanOrEqual]; 

如果你不熟悉PureLayout,這相當於調用

[NSLayoutConstraint constraintWithItem: attribute: relatedBy: toItem: attribute: multiplier: constant:0.0f]

還有其他的約束,把它的邊緣連接到superview,這是contentView的UITableViewCell

然而,當我打電話systemLayoutSizeFittingSize:對細胞的內容查看它似乎完全忽略了相對高度的限制,並將得到的細胞高度是遠遠太小,放不下的圖像。

如果我設置了一個明確的高度約束而不是相對的約束,這沒有問題。同樣,如果我繼承UIImageView並返回intrinsicContentSize中的顯式大小,則沒有問題。

我甚至試過在我UIImageView子類中的以下內容:

- (void) layoutSubviews { 
    [super layoutSubviews];  
    self.intrinsicSizeForAutolayout = self.frame.size;  
    [super layoutSubviews]; 
} 

- (CGSize)intrinsicContentSize { 
    return self.intrinsicSizeForAutolayout; 
} 

其中intrinsicSizeForAutolayout是我爲宗旨定義的屬性。我認爲這可能類似於設置preferredMaxLayoutWidthUILabel s解決類似問題的方式。

但是沒有。它不起作用。

這似乎我有一個替代使用醜陋的屏幕寬度檢查代碼有條件地設置一個固定的高度約束取決於屏幕寬度,我真的很想避免,因爲它有點挫敗使用自動佈局的目的第一個地方。

+0

致電前'systemLayoutSizeFittingSize:'在屏幕外的單元格的內容查看,你在屏幕外的單元格的寬度設置爲表視圖的實際寬度在那個時候(6&6 Plus將會> 320pt)?如果這沒有幫助,我建議嘗試使用iOS 8自身尺寸調整單元機制,以查看是否可以解決問題。如果這也行不通,我猜測你的約束可能存在一些問題......如果你可以修改其中一個[示例項目](https://github.com/smileyborg/TableViewCellWithAutoLayoutiOS8)來演示這將是最有幫助的問題。 – smileyborg 2014-11-21 17:57:07

+0

我將離屏單元的寬度設置爲表視圖的實際寬度。我想保持iOS 7的兼容性,所以我還沒有嘗試過iOS 8自行調整大小的單元機制。我會試着讓你得到一個示例項目來演示這個問題。 – mluisbrown 2014-11-22 21:06:42

+0

@smileyborg我試圖在iOS 7示例項目中重現問題而沒有成功。但是我發現在我的情況下,如果我使用Xcode 6視圖調試,'UIImageView'具有基於其內容大小的約束,而在修改後的示例項目中則沒有。我還應該補充一點,實際上我使用的是UIView-AutoLayout庫(PureLayout的前身),而不是PureLayout本身,儘管我懷疑這會有所作爲。 – mluisbrown 2014-11-23 01:33:46

回答

7

默認情況下,單元的寬度contentView沒有任何約束條件(它的寬度由SDK在添加到表格視圖時纔會設置),因此當您調用systemLayoutSizeFittingSize:時,約束求解器會假定它是當試圖找到有效的解決方案時,可以根據需要有效地壓縮寬度,這當然會導致錯誤的高度。

要修復此問題,可以將一個約束添加到contentView,該約束將其寬度修復爲最終的單元格/表格視圖寬度。這是有效的,因爲這個約束分解爲單元大小布局過程,導致systemLayoutSizeFittingSize:按預期工作。

使用PureLayout,我建議做這樣的事情:

[UIView autoSetPriority:UILayoutPriorityRequired - 1 forConstraints:^{ 
    [cell.contentView autoSetDimension:ALDimensionWidth toSize:CGRectGetWidth(tableView.bounds)]; 
}]; 

請注意,這不是一個壞主意,設定的低於所需的約束優先,只因爲這僅僅是爲了幫助尺寸設定操作,如果這種情況被破壞(可能是由於將來的SDK更改了表格視圖單元格的工作方式),則不需要發生異常。但這可能沒有關係。

此外,像往常一樣,你可能想確保這個約束只添加一次(不是每次調用tableView:heightForRowAtIndexPath:) - 這應該很容易做到。

在這裏看到一個具體的解決方案,以你的示例項目的叉:https://gist.github.com/smileyborg/0a2082a4d26fcc7fde4d