具有自动布局的自定义单元格的动态高度

Posted

技术标签:

【中文标题】具有自动布局的自定义单元格的动态高度【英文标题】:Dynamic Height for Custom Cell with Autolayout 【发布时间】:2015-04-07 14:06:07 【问题描述】:

我尝试使用自动布局构建不同的自定义单元格,但我总是得到默认高度 44。为了更好地理解:

GTBlockView 是我所有自定义单元格的超类,它是一个 UITableViewCell! 这适用于 ios 7 和 iOS 8,所以我不能使用新的自动功能... 我永远不知道单元格应该有多高,因为我从我的服务器获取数据!所以重要的是,一切都是动态的!

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 
return [self heightForBasicCellAtIndexPath:indexPath];



- (CGFloat)heightForBasicCellAtIndexPath:(NSIndexPath *)indexPath 

static GTBlockView *sizingCell = nil;
static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^
    sizingCell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
);

sizingCell = [self configureBasicCell:sizingCell atIndexPath:indexPath];

return [self calculateHeightForConfiguredSizingCell:sizingCell];



- (CGFloat)calculateHeightForConfiguredSizingCell:(GTBlockView *)sizingCell

    sizingCell.bounds = CGRectMake(0.0f, 0.0f, CGRectGetWidth(self.tableView.bounds), 0.0f);
    [sizingCell.contentView setNeedsLayout];
    [sizingCell.contentView layoutIfNeeded];

    CGSize size = [sizingCell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
    NSLog(@"HÖHE: %f",size.height);

    return size.height;





- (GTBlockView *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
return [self basicCellAtIndexPath:indexPath];



- (GTBlockView *)basicCellAtIndexPath:(NSIndexPath *)indexPath 

GTBlockView *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

if (cell == nil) 
    cell = [[GTBlockView alloc]
            initWithStyle:UITableViewCellStyleDefault
            reuseIdentifier:CellIdentifier];


[self configureBasicCell:cell atIndexPath:indexPath];
return cell;



- (GTBlockView*)configureBasicCell:(GTBlockView *)cellBlock atIndexPath:(NSIndexPath *)indexPath 

GFBlock *block = [self.node.blocks objectAtIndex:indexPath.row];

cellBlock = [[GTAppController sharedInstance] createInterfaceForBlock:block];

return cellBlock;

这是 Cell 的重要方法:

- (GTBlockView *)createInterfaceForBlock:(GFBlock *)block 

NSString* className = [self.interfacesDict objectForKey:NSStringFromBlockType(block.blockTypeId)];

Class c = nil;


if (className == nil)

    c = [GTGenericBlockView class];

 else 
    //Generate the specific Custom Cell Class
    c = NSClassFromString(className);


GTBlockView* instance = [(GTBlockView *)[c alloc] initWithBlock:block];


return instance;

在这里,我使用约束调用我的自定义单元之一:

- (id)initWithBlock:(GFBlock *)block 
self = [super initWithBlock:block];

if (self) 
        self.backgroundColor = GTDefaultBackgroundColor;

        self.button = [[UIButton alloc]init];
        self.button.translatesAutoresizingMaskIntoConstraints = NO;

        [self.contentView addSubview:self.button];


return self;




- (void)updateConstraints


if (!self.didSetupConstraints)

// 1. Create a dictionary of views
NSDictionary *viewsDictionary = @@"buttonView":self.button;
NSDictionary *metrics = @@"vSpacing":@0, @"hSpacing":@0;

// 3. Define the buttonView Position
NSArray *constraint_POS_V_SV = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[buttonView]"
                                                                       options:0
                                                                       metrics:metrics
                                                                         views:viewsDictionary];


NSArray *constraint_POS_H_SV = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-10-[buttonView]-10-|"
                                                                       options:0
                                                                       metrics:metrics
                                                                         views:viewsDictionary];


[self.contentView addConstraints:constraint_POS_V_SV];
[self.contentView addConstraints:constraint_POS_H_SV];

    NSArray *constraint_V = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[buttonView(==100)]"
                                                                options:0
                                                                metrics:nil
                                                                  views:viewsDictionary];
[self.button addConstraints:constraint_V];

   self.didSetupConstraints = YES;

[super updateConstraints];


但就像我上面说的,我总是得到默认高度,但在这种情况下它应该是 100.0f....

【问题讨论】:

一旦我遇到这样的问题,我通过使用tableView.rowHeight = 100.0f;tableView.estimatedRowHeight = 100.0f;解决了它 查看***.com/questions/29231390/… 问题是,高度必须是动态的,我不知道单元格应该有多大,因为我是从我的服务器获取的! 【参考方案1】:

在 viewDidLoad 中添加这个

tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 101

【讨论】:

查看本教程适用于 iOS7 github.com/smileyborg/TableViewCellWithAutoLayout/tree/master/…

以上是关于具有自动布局的自定义单元格的动态高度的主要内容,如果未能解决你的问题,请参考以下文章

使用自动布局自定义集合视图单元格的动态高度

UITableViewCell 具有嵌入式垂直堆栈视图设置,具有自动布局和动态高度

当我使用自动布局来选择每个单元格的高度(因此它们是动态的)时,它主要工作,但有些单元格有点短。为啥是这样?

多个自定义视图的自动布局问题

具有自动调整大小的单元格的自定义 UICollectionViewLayout 会因估计的项目高度较大而中断

自动布局:具有可变高度和两个标签的表格单元格