Autolayout UITableViewCell在视图中具有多个单元标识符

时间:2014-07-19 05:33:19

标签: ios uitableview ios7 autolayout

在我尝试使用100%自动布局驱动的表格视图时,包括从Using Auto Layout in UITableView for dynamic cell layouts & variable row heights的指令自动计算单元格高度,我在尝试混合两种不同的单元格类型时会看到一些奇怪的行为。同时查看相同的表格。

请参阅这些图像,这些图像显示了我仅使用单元格类型1或单元格类型2时的行为,以及当我尝试在同一个表视图中交替它们时的行为。对于非链接,我没有足够的声誉来发布链接。

TableCell1:

Image1

TableCell2:

Image2

两者在一起:

Image3

您可以看到前两幅图像中的细胞如何计算出完美的高度,以便在任何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 个答案:

答案 0 :(得分:0)

我知道这是一个老问题,但我最近在使用自动布局时在表格单元格中的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

}

希望这有帮助,如果我的描述不清楚,请告诉我。