[英]Table View Cell AutoLayout in iOS8
我似乎無法讓AutoLayout在我的Table View Cells上工作。
在某些細胞上它似乎起作用,而在其他細胞上似乎不起作用。 甚至是完全相同類型的細胞。
例如,在某些單元格上,描述將超過1行文本,它將正常工作...
...然而在其他單元格上,描述將超過1行的文本,但只顯示其中一行有一堆空白空間。
你能幫我弄清楚我錯過了什么或做錯了嗎? 謝謝!
我正在使用這個StackOverflow問題來指導我的過程作為第一個定時器執行此操作: 在UITableView中使用自動布局進行動態單元格布局和可變行高度
1.設置和添加約束
這些在我認為的大部分工作都很好。
2.確定唯一的表格視圖單元格重用標識符
我不完全確定我是否需要擔心這一部分,因為我總是會有標題,時間和描述。
對於iOS 8 - 自調整單元格3.啟用行高度估計
我將此添加到viewDidLoad
:
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 180.0;
更新:每個Acey請求添加更多信息
為了清楚起見,我提出了約束條件:
更新2:解決下面的答案工作得很好,但任何額外的間距都是由於單元格的高度設置太大,因此Xcode自動添加額外的空間來填充單元格的高度,因為文本標簽沒有填滿整個高度表視圖單元格。
如果您遇到此問題並遇到相同問題,請告訴我您是否有任何疑問或需要任何幫助。
感謝大家!
我還沒有嘗試過使用新的iOS 8機制。 但是當我使用iOS 6/7進行此操作時,我遇到了類似的問題。在將應用程序更新到iOS 8后,它仍然可以正常工作,所以也許舊的方式仍然是最好的方式?
我在這里有一些代碼示例: AutoLayout多行UILabel切斷了一些文本
在這里: AutoLayout uitableviewcell在風景和iPad上計算基於肖像iPhone的高度
長話短說明iOS 8之前的方法涉及保留一個單元格的副本,僅用於計算tableView:heightForRowAtIndexPath:
的高度tableView:heightForRowAtIndexPath:
. 但這還不足以處理多線UILabel
。 每次調用layoutSubviews
,我都必須UILabel
以更新preferredMaxLayoutWidth
。
preferredMaxLayoutWidth
“修復”似乎是我失蹤的神奇秘密。 一旦我這樣做,我的大部分細胞都能完美地運作。
第二個問題我只要求我正確設置內容壓縮阻力和內容擁抱屬性,因此例如告訴標簽擁抱文本將意味着它不會擴展以填充將導致單元格縮小的空白。
一旦我完成了這兩件事,我的單元格現在可以處理任何字體大小或任何數量的文本而沒有任何雜亂的布局代碼。 這需要學習很多,但我認為它最終得到了回報,因為我的應用程序中有很多動態內容。
編輯
在使用iOS 8遇到我自己的幾個問題之后,我添加了一些更多細節來解決這些非常奇怪的autoLayout錯誤。
使用我提到的代碼,當單元格“行高”未設置為自定義時,它似乎不起作用。 通過選擇單元格並單擊autoLayout選項卡(其中所有內容壓縮阻力設置等),可以在IB中找到此設置。 按復選框,它將填充臨時高度。
其次,在我的代碼中,我保留了一個單元格的本地副本,然后在heightForRowAtIndexPath:
方法中多次重復使用它。 這似乎每次調用時都會增加細胞高度。 我不得不通過調用以下方式重新啟動本地副本:
localCopy = [self.tableView dequeueReusableCellWithIdentifier:@"mycell"];
看起來新的Xcode 6 / iOS 8變化非常不與iOS 7向后兼容,並且它的管理方式似乎完全不同。
希望這可以幫助。
編輯2
看完這個問題后: iOS AutoLayout多行UILabel
我遇到了iOS 7 / iOS 8自動布局支持的另一個問題! 我重寫了iOS 8的layoutSubviews
我還需要覆蓋setBounds
以在調用super之后更新preferredMaxLayoutWidth
。 WTF改變了蘋果!
對於preferredMaxLayoutWidth
,IB的設置似乎是一個問題,因為iOS 7不能使用自動功能,如果你在多個設備上使用相同的UILabel
,它只會使用1寬度。 因此,iOS 8平板電腦上的UITableViewCell
會更大,因為相同的手機需要在iOS 8 iPhone上擁有2條線路。
這是我的嘗試。
您可以創建一個方法/函數,讓您獲得所需的單元格視圖。 像這樣:
- (UIView *) getCellView {
UIView *cellView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, self.view.frame.size.width, 0.0f)];
cellView.tag = 1;
cellView.backgroundColor = [UIColor clearColor];
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(15.0f, 10.0f, 15.0f, 15.0f)]; //I assumed that was the size of your imageView;
imgView.image = [UIImage imageNamed:@"whatever-your-image-is-called"];
[cellView addSubview:imgView];
CGFloat xPadding = 15.0f;
CGFloat yPadding = 15.0f;
UILabel *headlineLabel = [[UILabel alloc ]initWithFrame:CGRectMake(xPadding, 0.0f, self.view.frame.size.width - (xPadding*2), 0.0f)];
headlineLabel.numberOfLines = 0;
headlineLabel.text = @"Red Sox season fell apart after World Series title (The Associated Press)";
[headlineLabel sizeToFit];
CGRect hFrame = headlineLabel.frame;
if(hFrame.size.width > self.view.frame.size.width - 31.0f)
hFrame.size.width = self.view.frame.size.width - 30.0f;
hFrame.origin.y = imgView.frame.size.height + yPadding;
headlineLabel.frame = hFrame;
UILabel *timeLabel = [[UILabel alloc] initWithFrame:CGRectMake(xPadding, 0.0f, self.view.frame.size.height-(xPadding*2), 0.0f)];
timeLabel.text = @"4h";
//timeLabel.numberOfLines = 0; //uncomment if it will wrap on multiple lines;
[timeLabel sizeToFit];
hFrame = timeLabel.frame;
if(hFrame.size.width > self.view.frame.size.width - 31.0f)
hFrame.size.width = self.view.frame.size.width - 30.0f;
hFrame.origin.y = headlineLabel.frame.size.height + yPadding;
timeLabel.frame = hFrame;
UILabel *descriptLabel = [[UILabel alloc] initWithFrame:CGRectMake(xPadding, 0.0f, self.view.frame.size.height - (xPadding*2), 0.0f)];
descriptLabel.text = @"Boston (AP) -- To Boston Red Sox manager John Farrel, it hardly seems possible that just 11 months ago his team was celebrating the World Series championship on the field at Fenway Park.";
descriptLabel.numberOfLines = 0; //I would suggest something like 4 or 5 if the description string vary from 1 line to more than 5 lines.
[descriptLabel sizeToFit];
hFrame = descriptLabel.frame;
if(hFrame.size.width > self.view.frame.size.width - 31.0f)
hFrame.size.width = self.view.frame.size.width - 30.0f;
hFrame.origin.y = timeLabel.frame.size.height + yPadding;
descriptLabel.frame = hFrame;
cellView.frame = CGRectMake(0.0f, 0.0f, self.view.frame.size.width, descriptLabel.frame.origin.y + descriptLabel.frame.size.height + 15.0f /*some padding*/);
return cellView;
}
如果您正在使用indexPath.row,您可以將方法名稱更改為- (UIView *)getCellView:(NSIndex) *indexPath
,它應該工作相同。
然后在你的heightForRowAtIndexPath你可以做到
return [[self getCellView] frame].size.height;
要么
return [[self getCellView:indexPath] frame].size.height
在您的cellForRowAtIndexPath中,您可以執行以下操作
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
cell.accessoryType = UITableViewCellAccessoryNone;
cell.textLabel.text = @"";
cell.detailTextLabel.text = @"";
}
[[cell viewWithTag:1] removeFromSuperview];
[cell addSubview:[self getCellView]; //or [cell addSubview:[self getCellView:indexPath]];
return cell;
希望這可以幫助。 如果有什么東西不清楚或不能正常工作,請告訴我。 您可能需要調整一些內容以適應您的使用情況,尤其是在cellForRowAtIndexPath中,但這應該是您需要的所有內容。 快樂的編碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.