簡體   English   中英

可變長度標簽,tableview行高和自動布局

[英]Variable length label, tableview row heights, and auto layout

在SO和其他地方有很多關於如何根據子視圖的大小計算UITableView行的必要高度的好信息。 典型的例子和我在這里應用的例子是一個包含帶有可變長度文本的標簽的單元格。

在此輸入圖像描述

通常的建議是在tableview的heightForRowAtIndexPath:使用sizeWithFont:constrainedToSize:lineBreakMode: heightForRowAtIndexPath: . 但是我見過的大多數例子都是根據標簽的已知寬度使用“魔術”數字。

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

這是我對此(以及更標准)方法的主要問題。 當單元格處於編輯模式時,標簽的寬度會更改以適應編輯附件。 由於行高是常量,並且標簽使用自動布局,因此其高度會增加。

在此輸入圖像描述

所需的行為是標簽的高度保持不變,必要時應使用截斷。

我在哪里以及如何實現這個? 我應該在單元格的setEditing中做些什么嗎? 可能會添加另一個約束來限制高度,並啟用截斷,編輯時會應用相反的== NO? “滑動刪除”模式怎么樣 - 我認為這不會觸發setEditing? 那么layoutSubview - 我可以在那里做些什么嗎?

我嘗試了很多東西 - 我得到的最接近的是覆蓋layoutSubviews,測試用戶是否已切換到編輯模式,如果是這樣,首先捕獲標簽的內在高度,然后添加臨時約束來強制執行(當時退出編輯模式)。 除了少數邊緣情況外,它運作良好。

但后來我開始考慮更多的自動布局。 我想要達到什么目的? 當寬度減小時,我不希望標簽長得更高。 這是一個非常簡單的約束:

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

添加此附加約束效果很好。 請注意,我還會在編輯時將換行符模式切換為截斷:

在此輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM