简体   繁体   English

iOS UITableView中的可变单元格高度具有代码中的自动布局约束

[英]Variable cell height in iOS UITableView with auto layout constraints in code

I have a view controller which has a UITableView instance and uses auto layout constraints to render it. 我有一个具有UITableView实例并使用自动布局约束来呈现它的视图控制器。 I would like to have variable cell heights in this table view. 我想在此表视图中具有可变的单元格高度。 I do not want to calculate the cell height myself because I have a complex cell content composed of several labels and images that can vary from cell to cell. 我不想自己计算像元高度,因为我有一个复杂的像元内容,它由几个标签和图像组成,每个像元之间可能会有所不同。 I do believe it is possible to let the auto-layout cell to resize itself so it contains all its subviews (ie using sizeToFit method of labels after assigning text to them?). 我确实相信可以让自动布局单元格调整其自身的大小,使其包含其所有子视图(即,在将文本分配给它们之后使用sizeToFit标签方法吗?)。

I have a custom cell class that uses visual constraints format of auto layout to position its subviews. 我有一个自定义单元格类,该类使用自动布局的视觉约束格式来定位其子视图。 I tried to incorporate the method proposed in here and its sample implementation here . 我试图纳入提出的方法在这里和它的样本实现在这里

When I initialize the table view, I create an array with the equal length of my data rows and calculate each row's height by assigning values to a prototype cell of type MyCustomCell and retrieve its height using this 初始化表格视图时,我将创建一个数据行长度相等的数组,并通过将值分配给MyCustomCell类型的原型单元格来计算每行的高度,并使用此值来获取其高度

[cell systemLayoutSizeFittingSize:UILayoutFittingExpandedSize].height

and storing it in the heights array so to use it later in heightForRowAtIndexPath method of table view to retrieve the correct cell height for individual cells. 并将其存储在heights数组中,以便以后在表视图的heightForRowAtIndexPath方法中使用它来检索单个单元格的正确单元格高度。

Doing all these, however, I end up with an unreadable exception NSInternalInconsistencyException in xCode with "Cannot find an outgoing row head for incoming head MyCustomCell:0xa8a1430.Width, which should never happen." 但是,完成所有这些操作后,我在xCode遇到了一个无法读取的异常NSInternalInconsistencyException ,其内容为“无法为传入的头MyCustomCell:0xa8a1430.Width找到传出的行头,这永远不会发生。”

Here is the initialization of the subviews in my custom cell: 这是自定义单元格中子视图的初始化:

    _titleLabel = [[UILabel alloc] init];
    _titleLabel.font = [TSTheme boldThemeFontOfSize:TSThemeFontSizeSmall];
    _titleLabel.textColor = [[TSTheme sharedTheme] darkTextColor];
    _titleLabel.backgroundColor = [UIColor clearColor];
    _titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
    _titleLabel.font = [UIFont fontWithName:@"HelveticaNeue-CondensedBold" size:19];
    _titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
    [self.contentView addSubview:_titleLabel];

    _summaryLabel = [[UILabel alloc] init];
    _summaryLabel.font = [TSTheme boldThemeFontOfSize:TSThemeFontSizeSmall];
    _summaryLabel.backgroundColor = [UIColor clearColor];
    _summaryLabel.textColor = [[TSTheme sharedTheme] darkTextColor];
    _summaryLabel.translatesAutoresizingMaskIntoConstraints = NO;
    _summaryLabel.numberOfLines = 0;
    _summaryLabel.preferredMaxLayoutWidth = 250.0f; // required for text wrapping
    _summaryLabel.font = [UIFont fontWithName:@"Georgia" size:14];
    _summaryLabel.lineBreakMode = NSLineBreakByWordWrapping;
    [self.contentView addSubview:_summaryLabel];

    _thumbnailView = [[UIImageView alloc] init];
    _thumbnailView.translatesAutoresizingMaskIntoConstraints = NO;

    [self.contentView addSubview:_thumbnailView];

and the constraints for my custom cell are as follow 我的自定义单元格的约束如下

NSDictionary *views = NSDictionaryOfVariableBindings(_titleLabel, _summaryLabel, _thumbnailView);
NSDictionary *metrics = @{@"margin": @"5"};

[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(margin)-[_thumbnailView(<=60)]-(margin)-[_titleLabel]-(margin)-|"
                                                                         options:0
                                                                         metrics:metrics
                                                                           views:views]];

[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(margin)-[_thumbnailView]-(margin)-|"
                                                                         options:0
                                                                         metrics:metrics
                                                                           views:views]];


[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(margin)-[_titleLabel]-(0)-[_summaryLabel]"
                                                                         options:0
                                                                         metrics:metrics
                                                                           views:views]];


[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(margin)-[_thumbnailView]-(margin)-[_summaryLabel]-(margin)-|"
                                                                         options:0
                                                                         metrics:metrics
                                                                           views:views]];

I encountered this when I used a table view cell that was added directly as a prototype to a UITableView in a storyboard and used dequeueReusableCellWithIdentifier: to get the cell for caching the heights. 当我使用直接作为原型添加到情节提要中的UITableView的表格视图单元并使用dequeueReusableCellWithIdentifier:来获取用于缓存高度的单元时,我遇到了此问题。

If I moved the cell into a separate nib then it instantiated the cell for determining heights directly from the nib the problem went away. 如果我将单元移到一个单独的笔尖中,那么它将实例化该单元以直接从笔尖确定高度,问题就消失了。

Then you can register the nib with the UITableView. 然后,您可以在UITableView中注册笔尖。 Hope this helps. 希望这可以帮助。

I used this code to calculate dinamically the hieght of a row because the content of each one was different: 我使用此代码来动态地计算一行的高度,因为每个内容的内容都不相同:

-(CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ // Hacer que el tamaño de la celda sea variable dependiendo del tamaño del texto a mostrar

    NoticiaAsignatura_DTO *rowData = [[NoticiaAsignatura_DTO alloc] init];

    rowData = [self.listaNoticias objectAtIndex:[indexPath row]];

    NSString *text = rowData.title;
    text = [text stringByAppendingString:@"\n"];
    text = [text stringByAppendingString: rowData.publish_date_ansi];
    text = [text stringByAppendingString:@"\n\n"];
    text = [text stringByAppendingString:rowData.content];
    text = [text stringByAppendingString:@"\n\n"];

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad){

        CGSize constraint = CGSizeMake(700,200000.0);
        CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:NSLineBreakByWordWrapping];
        return size.height + (CELL_CONTENT_MARGIN * 2);
    }
    else{
        CGSize constraint = CGSizeMake(300,200000.0);
        CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE_PHONE] constrainedToSize:constraint lineBreakMode:NSLineBreakByWordWrapping];
        NSLog(@"Size: %f ", size.height);
        return size.height + (CELL_CONTENT_MARGIN * 2);
    }

}

Hope it helps. 希望能帮助到你。

  • Assign and implement tableview dataSource and delegate 分配并实现tableview数据源和委托
  • Assign UITableViewAutomaticDimension to rowHeight & estimatedRowHeight UITableViewAutomaticDimension分配给rowHeight和estimatedRowHeight
  • Implement delegate/dataSource methods (ie heightForRowAt and return a value UITableViewAutomaticDimension to it) 实现委托/数据源方法(即heightForRowAt并向其返回值UITableViewAutomaticDimension

- -

Objective C: 目标C:

// in ViewController.h
#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>

  @property IBOutlet UITableView * table;

@end

// in ViewController.m

- (void)viewDidLoad {
    [super viewDidLoad];
    self.table.dataSource = self;
    self.table.delegate = self;

    self.table.rowHeight = UITableViewAutomaticDimension;
    self.table.estimatedRowHeight = UITableViewAutomaticDimension;
}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

    return UITableViewAutomaticDimension;
}

Swift: 迅速:

@IBOutlet weak var table: UITableView!

override func viewDidLoad() {
    super.viewDidLoad()

    // Don't forget to set dataSource and delegate for table
    table.dataSource = self
    table.delegate = self

    // Set automatic dimensions for row height
    table.rowHeight = UITableViewAutomaticDimension
    table.estimatedRowHeight = UITableViewAutomaticDimension
}



// UITableViewAutomaticDimension calculates height of label contents/text
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

For label instance in UITableviewCell 对于UITableviewCell中的标签实例

  • Set number of lines = 0 (& line break mode = truncate tail) 设置行数= 0(&换行模式=截尾)
  • Set all constraints (top, bottom, right left) with respect to its superview/ cell container. 设置关于其superview /单元容器的所有约束(上,下,左左)。
  • Optional : Set minimum height for label, if you want minimum vertical area covered by label, even if there is no data. 可选 :即使没有数据,如果您希望标签覆盖最小的垂直区域,请设置标签的最小高度。

在此处输入图片说明

Note : If you've more than one labels (UIElements) with dynamic length, which should be adjusted according to its content size: Adjust 'Content Hugging and Compression Resistance Priority` for labels which you want to expand/compress with higher priority. 注意 :如果您具有多个具有动态长度的标签(UIElements),则应根据其内容大小进行调整:对于要以更高优先级进行扩展/压缩的标签,请调整“内容拥抱和抗压缩优先级”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 iOS 7/8 UITableView Cell:两个UILabel,动态高度,自动布局,可变行高 - iOS 7/8 UITableView Cell: Two UILabels with dynamic height with auto layout for variable row height iOS:在“自动布局”下更改UITableView的高度 - iOS: Change UITableView height under Auto Layout 如何使用“自动布局”约束将2个具有可变大小的标签放入表格单元格中,该表格单元格的高度是使用EstimateHeightForRowAtIndexPath估算的 - How to use Auto Layout constraints to fit 2 labels with variable size in a table cell which height is estimated using estimatedHeightForRowAtIndexPath UITableView中的自动布局约束问题 - Auto Layout Constraints Issue in UITableView iOS 8上的自动布局约束 - Auto layout constraints on iOS 8 iOS自动布局约束 - IOS auto layout constraints iOS-表格单元格动态高度的布局限制指南 - iOS - layout constraints guide for dynamic height of table cell 自动布局约束-垂直间距,其中一件高度可变 - Auto layout constraints - Vertical spacing with one item of variable height iOS 8自动单元格高度 - didSelectRowAtIndexPath导致UItableview跳转到顶部 - iOS 8 Auto cell height - didSelectRowAtIndexPath causes UItableview to jump to top 在 UITableView 中使用自动布局进行动态单元格布局和可变行高 - Using Auto Layout in UITableView for dynamic cell layouts & variable row heights
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM