视图中具有多个单元格标识符的自动布局 UITableViewCell
Posted
技术标签:
【中文标题】视图中具有多个单元格标识符的自动布局 UITableViewCell【英文标题】:Autolayout UITableViewCell with multiple cell identifiers in view 【发布时间】:2014-07-19 05:33:18 【问题描述】:在我尝试使用 100% 自动布局驱动的表格视图时,包括根据 Using Auto Layout in UITableView for dynamic cell layouts & variable row heights 的说明自动计算单元格高度,我在尝试在同一个表格中混合两种不同的单元格类型时看到了一些奇怪的行为同时查看。
查看这些图像,这些图像显示了我仅使用单元格类型 1 或单元格类型 2 以及尝试在同一个表格视图中交替使用它们时的行为。抱歉,没有链接,我还没有足够高的声誉来发布链接。
TableCell1:
TableCell2:
两者一起:
您可以看到在前 2 张图片中,单元格显示的高度是经过计算的,因此在任何 UILabel 元素的上方或下方都不会显示额外的空间。在第三张图片中,我在类型 1 和类型 2 的单元格之间交替,没有进行任何额外的代码更改。当显示单个单元格标识符时,高度可以完美计算,即使文本比前一个单元格长或短。混合它们时我会出现奇怪的行为。
#import "TableViewController.h"
#import "TableViewCell.h"
@interface TableViewController ()
@end
@implementation TableViewController
- (instancetype)initWithStyle:(UITableViewStyle)style
self = [super initWithStyle:style];
if (self)
// Custom initialization
return self;
- (void)viewDidLoad
[super viewDidLoad];
_lipsumArray = [[NSMutableArray alloc] init];
for (int i=0; i < 10; i++)
[_lipsumArray addObject:[self randomLorem]];
- (void)didReceiveMemoryWarning
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
return 1;
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
return _lipsumArray.count;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
return [self basicCellAtIndexPath:indexPath];
- (TableViewCell *)basicCellAtIndexPath:(NSIndexPath *)indexPath
NSString *identifier = ([indexPath row] % 2) ? @"TableCell1" : @"TableCell2";
TableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];
[self configureTableCell:cell atIndexPath:indexPath];
return cell;
- (void)configureTableCell:(TableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
cell.mainText.text = [_lipsumArray objectAtIndex:indexPath.row];
cell.mainText.font = [UIFont fontWithName:@"Avenir-Medium" size:18.0];
cell.otherText.text = [self textForOriginalBody:[_lipsumArray objectAtIndex:indexPath.row]];
cell.otherText.font = [UIFont fontWithName:@"Avenir-Medium" size:14.0];
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
static TableViewCell *sizingCell = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^
NSString *identifier = ([indexPath row] % 2) ? @"TableCell1" : @"TableCell2";
sizingCell = [self.tableView dequeueReusableCellWithIdentifier:identifier];
);
[self configureTableCell:sizingCell atIndexPath:indexPath];
[sizingCell setNeedsLayout];
[sizingCell layoutIfNeeded];
CGSize size = [sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
return size.height;
- (NSString*)randomLorem
NSString *loremIpsum = @"Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Nam liber te conscient to factor tum poen legum odioque civiuda.";
NSArray *loremArray = [loremIpsum componentsSeparatedByString:@" "];
int r = arc4random() % [loremArray count];
r = MAX(3, r); // no less than 3 words
NSArray *loremRandom = [loremArray objectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, r)]];
return [NSString stringWithFormat:@"%@", [loremRandom componentsJoinedByString:@" "]];
- (NSString*)textForOriginalBody:(NSString*)originalBody
if (originalBody.length > 80)
originalBody = [NSString stringWithFormat:@"%@...", [originalBody substringToIndex:80]];
return originalBody;
@end
什么可能导致这种行为?
【问题讨论】:
【参考方案1】:我知道这是一个老问题,但我最近在使用自动布局时遇到了类似的问题,即表格单元格中 uilabels 的随机高度问题。我不知道发生这种情况的技术原因,但是在计算高度时没有满足宽度依赖性,这就是导致奇怪布局的原因。
为了解决这个问题,我必须对我的表格视图单元格进行子类化,然后覆盖 layoutSubviews 方法并在每个标签上设置 preferredMaxLayoutWidth 值,这会导致我对它自己的框架宽度产生问题。这是我可以转换为 Obj-C 的快速代码:
override func layoutSubviews()
super.layoutSubviews()
self.contentView.layoutIfNeeded()
self.acCaptionLabel.preferredMaxLayoutWidth = self.acCaptionLabel.frame.size.width
self.acDataDetails.preferredMaxLayoutWidth = self.acDataDetails.frame.size.width
self.acCommentsLabel.preferredMaxLayoutWidth = self.acCommentsLabel.frame.size.width
希望这会有所帮助,如果我的描述不清楚,请告诉我。
【讨论】:
以上是关于视图中具有多个单元格标识符的自动布局 UITableViewCell的主要内容,如果未能解决你的问题,请参考以下文章
XCUITest:从具有多个单元格原型的多个单元格标识符中选择一个 CollectionView 单元格