2013-08-20 70 views
5

有很多關於SO和elsewhere的很好的信息,關於如何根據子視圖的大小計算UITableView行所需的高度。典型的例子和我在這裏應用的例子是一個包含可變長度文本標籤的單元格。可變長度標籤,tableview行高和自動佈局

enter image description here

通常的建議是在tableview中的heightForRowAtIndexPath:使用sizeWithFont:constrainedToSize:lineBreakMode:。但是我見過的大多數例子都是基於已知的標籤寬度使用「魔術」數字。

CGSize constraint = CGSizeMake(224.0, MAXFLOAT); //224 is known to be the width available 
CGSize labelSize = [cellText sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:NSLineBreakByWordWrapping]; 

一些更好的例子可能使用的tableview的邊界,然後減去幻數或常數單元格中的其他意見,這至少是更清晰一點(如果邊界改變旋轉等效果更好) 。

CGSize constraint = CGSizeMake(self.tableview.bounds.size.width - 20 - 10 - 36 - 20, MAXFLOAT); //each non-label width subtracted 
CGSize labelSize = [cellText sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:NSLineBreakByWordWrapping]; 

這是常見的方法,但它似乎缺乏。誰能說其他單元格子視圖的寬度,甚至是字體,都保證不會改變(或者在兩個地方都會一直在努力改變)?

我決定寧願讓單元格負責提供這個高度。細胞總是知道它的屬性。爲了達到這個目的,我首先將單元格中的所有佈局代碼都引用了一些局部常量。然後,我在自定義單元類中添加了一個類方法,該類可以根據自己的字體和調整常量返回給定文本所需的高度。

+ (CGFloat)heightRequiredForText:(NSString *)text usingWidth:(CGFloat)width 
{ 
    //a class method that tells the caller how much height is needed for the provided text, based on the cell's size and font constants 
    CGSize constraintSize = CGSizeMake(width - kMargin - kGap - kMargin - kCheckboxWidth, MAXFLOAT); 
    CGRect bounds = [text boundingRectWithSize:constraintSize 
               options:NSStringDrawingUsesLineFragmentOrigin 
              attributes:@{NSFontAttributeName:self.labelFont} 
               context:nil]; 
    return bounds.size.height; 
} 

這允許UITableViewController只提供文本和當前邊界的寬度(即tableview的寬度)。字體和佈局可以在單元格子類中更改,並且所有內容都繼續「正常工作」。

問題1

正如一個方面說明,這是合理的?有沒有更好的方法來實現相同的目標?

問題2

這裏是我與這個具有主要問題(和更標準)的做法。當單元格處於其編輯模式時,標籤寬度會發生變化以適應編輯附件。由於行高不變,並且標籤使用自動佈局,因此其高度會增加。

enter image description here

所需行爲是標籤的高度保持恆定和截斷時,應使用必要的。

在哪裏以及如何實現?我應該在單元格的編輯中做些什麼:?也許增加另一個約束來限制高度,並打開截斷,在編輯== NO時應用相反的約束?怎麼樣'刷卡刪除'模式 - 我不認爲這觸發setEditing?怎麼樣layoutSubview - 我可以在那裏做點什麼?

+0

我推薦的方法是使用[原型單元例(http://stackoverflow.com/questions/13660004/retrieve-custom -prototype-cell-height-from-storyboard/14127936#14127936)這種事情。 –

回答

1

我嘗試了很多東西 - 我得到的最接近的是重寫layoutSubviews,測試用戶是否切換到編輯模式,如果是這樣,先捕獲標籤的內在高度,然後添加一個臨時約束來強制執行它然後在脫離編輯模式時被移除)。除了一些邊緣情況,它運作良好。

但後來我開始考慮更多的汽車佈局。我想達到什麼目的?當寬度減小時,我不希望標籤變長。這是一個非常簡單的約束:

[self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:self.label 
                    attribute:NSLayoutAttributeHeight 
                    relatedBy:NSLayoutRelationLessThanOrEqual 
                     toItem:self.contentView 
                    attribute:NSLayoutAttributeHeight 
                    multiplier:1 
                    constant:0]]; 

添加這個額外的約束效果很好。請注意,我也轉換行模式截斷上編輯:

enter image description here

相關問題