UITableViewCell无法自动调整大小 [英] UITableViewCell not autosizing

查看:65
本文介绍了UITableViewCell无法自动调整大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在UITableViewCell子类中有两个标签.我希望两个标签都是多行标签,所以我已经将它们的行数都设置为零.但是问题是我的表视图单元格没有扩展.实际上,即使我在两个方向上将两个标签的耐压性优先级都设置为1000,这些标签也都被压扁了.

I have two labels in a UITableViewCell subclass. I want both labels to be multiline labels, so I have set the number of lines to zero for both of them. But the problem is that my table view cell is not expanding. In fact, the labels are getting squished so much even though I have the compression resistance priority set to 1000 for both labels in both directions.

我将 firstLabel UILabel属性的背景设置为橙色,并且将 secondLabel UILabel属性的背景设置为黄色,以便于查看标签.每行之间都有一个分隔线,以使高度更容易看到.

I have set the background of the firstLabel UILabel property to orange and the background of the secondLabel UILabel property to yellow to make it easier to see the labels. There is also a divider between each row to make it so the heights are easier to see.

这是在设备上运行时视图的外观.标签全部被压缩,无论我添加多少约束或标签中包含多少内容,行的大小都不会增加.另外,第一行中的第一个标签具有足够的内容,应该多于一行,但是它会被 ... 截断.

Here is what the view looks like when run on a device. The labels are all compressed and the rows never increase in size no matter how much padding I add to the constraints or how much content I put in the labels. Additionally, the first label in the first row has enough content that it should be more than one line, but it is getting truncated with ....

这是我正在使用的代码.第一部分是具有两个标签的表格视图单元子类-firstLabel(左侧的标签)和secondLabel(右侧的标签).接下来,我有具有表视图的视图代码,并显示了如何配置表视图.最后,有一个UITableView子类,该子类将表的InternalContentSize设置为表的内容大小.我添加它是因为没有它,表框架始终保持为零,因此不会调用表视图数据源方法.如果有人也知道更好的方法,那将不胜感激.

Here is the code I am using for this. The first part is the table view cell subclass that has the two labels - firstLabel (the one on the left) and secondLabel (the one on the right). Next, I have the code for the view that has the table view and shows how the table view is configured. Finally, there is a UITableView subclass that sets the intrinsicContentSize of the table to be the content size of the table. I added this because without this the table frame always stayed at zero and so the table view data source methods were not getting called. If anyone knows a better way to do this too, that would be much appreciated.

这是我的UITableViewCell的实现.它是通过编程方式使用的,所以我

This is the implementation for my UITableViewCell. It is used programmatically, so I am

@interface MyTableViewCell ()

@property (strong, nonatomic) UILabel *firstLabel;
@property (strong, nonatomic) UILabel *secondLabel;

@end

@implementation MyTableViewCell

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
        [self initialize];
    }
    return self;
}

- (void)initialize {
    [self.contentView setBackgroundColor:[UIColor systemTealColor]];
    [self.backgroundView setBackgroundColor:[UIColor systemGrayColor]];
    
    [self addSubview:self.firstLabel];
    [self addSubview:self.secondLabel];
    
    NSLayoutConstraint *heightConstraint = [self.heightAnchor constraintEqualToConstant:1.0f];
    [heightConstraint setPriority:50];
    
    [NSLayoutConstraint activateConstraints:@[
        [self.firstLabel.leadingAnchor constraintEqualToAnchor:self.contentView.layoutMarginsGuide.leadingAnchor],
        [self.firstLabel.topAnchor constraintEqualToAnchor:self.contentView.layoutMarginsGuide.topAnchor],
        [self.firstLabel.trailingAnchor constraintEqualToAnchor:self.centerXAnchor constant:-4.0f],
        
        [self.secondLabel.leadingAnchor constraintEqualToAnchor:self.centerXAnchor constant:4.0f],
        [self.secondLabel.topAnchor constraintEqualToAnchor:self.contentView.layoutMarginsGuide.topAnchor],
        [self.secondLabel.trailingAnchor constraintEqualToAnchor:self.contentView.layoutMarginsGuide.trailingAnchor],
        
        [self.contentView.layoutMarginsGuide.bottomAnchor constraintGreaterThanOrEqualToAnchor:self.firstLabel.bottomAnchor constant:20.0f],
        [self.contentView.layoutMarginsGuide.bottomAnchor constraintGreaterThanOrEqualToAnchor:self.secondLabel.bottomAnchor constant:20.0f],
        
        heightConstraint
    ]];
}

- (UILabel *)firstLabel {
    if (!self->_firstLabel) {
        self->_firstLabel = [[UILabel alloc] init];
        self->_firstLabel.translatesAutoresizingMaskIntoConstraints = NO;
        self->_firstLabel.numberOfLines = 0;
        self->_firstLabel.userInteractionEnabled = NO;
        self->_firstLabel.contentMode = UIViewContentModeScaleToFill;
        [self->_firstLabel setContentHuggingPriority:251 forAxis:UILayoutConstraintAxisHorizontal];
        [self->_firstLabel setContentHuggingPriority:251 forAxis:UILayoutConstraintAxisVertical];
        [self->_firstLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
        [self->_firstLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];
        self->_firstLabel.textAlignment = NSTextAlignmentNatural;
        self->_firstLabel.lineBreakMode = NSLineBreakByTruncatingTail;
        self->_firstLabel.baselineAdjustment = UIBaselineAdjustmentAlignBaselines;
        self->_firstLabel.adjustsFontSizeToFitWidth = NO;
        self->_firstLabel.backgroundColor = [UIColor orangeColor];
    }
    return self->_firstLabel;
}

- (UILabel *)secondLabel {
    if (!self->_secondLabel) {
        self->_secondLabel = [[UILabel alloc] init];
        self->_secondLabel.translatesAutoresizingMaskIntoConstraints = NO;
        self->_secondLabel.numberOfLines = 0;
        self->_secondLabel.userInteractionEnabled = NO;
        self->_secondLabel.contentMode = UIViewContentModeScaleToFill;
        [self->_secondLabel setContentHuggingPriority:251 forAxis:UILayoutConstraintAxisHorizontal];
        [self->_secondLabel setContentHuggingPriority:251 forAxis:UILayoutConstraintAxisVertical];
        [self->_secondLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
        [self->_secondLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];
        self->_secondLabel.textAlignment = NSTextAlignmentNatural;
        self->_secondLabel.lineBreakMode = NSLineBreakByTruncatingTail;
        self->_secondLabel.baselineAdjustment = UIBaselineAdjustmentAlignBaselines;
        self->_secondLabel.adjustsFontSizeToFitWidth = NO;
        self->_secondLabel.backgroundColor = [UIColor yellowColor];
    }
    return self->_secondLabel;
}

- (void)setData:(MyModel *)data {
    self.firstLabel.text = data.first;
    self.secondLabel.text = data.second;
    [self invalidateIntrinsicContentSize];
}

@end

主视图-将表格视图作为子视图

这是显示的实际视图.作为较大应用程序的一部分,该视图然后显示在垂直的UIStackView中.

Primary View - has a table view as a child view

This is the actual view that is displayed. As part of the larger application, this view is then displayed in a vertical UIStackView.

此视图具有一个表视图作为唯一的子视图,并且该表视图通过AutoLayout固定到该视图的边缘.UITableView实际上是另一个名为"AutosizingTableView"的类的实例.要使表格视图自动调整大小(如果没有此设置,表格的框架将保持为零,并且由于表格高度为零,因此从未调用过表格视图数据源方法 tableView:cellForRowAtIndexPath:).此表视图的代码包含在本节之后.

This view has a table view as the only subview and the table view is pinned to the edges of this view with AutoLayout. The UITableView is actually an instance of another class called "AutosizingTableView" to get the table view to autosize (without this, the frame of the table stays at zero and the table view data source method, tableView:cellForRowAtIndexPath:, was never being called since the table height was zero. The code for this table view is included after this section.

@interface MyView ()

@property (strong, nonatomic) AutosizingTableView *tableView;

@end

@implementation MyView

- (instancetype)init {
    return [self initWithFrame:CGRectZero];
}

- (instancetype)initWithCoder:(NSCoder *)coder {
    if (self = [super initWithCoder:coder]) {
        [self initialize];
    }
    return self;
}

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        [self initialize];
    }
    return self;
}

- (void)initialize {
    [self addSubview:self.tableView];
    
    [NSLayoutConstraint activateConstraints:@[
        [self.tableView.leadingAnchor constraintEqualToAnchor:self.leadingAnchor],
        [self.tableView.topAnchor constraintEqualToAnchor:self.topAnchor],
        [self.tableView.trailingAnchor constraintEqualToAnchor:self.trailingAnchor],
        [self.tableView.bottomAnchor constraintEqualToAnchor:self.bottomAnchor],
        [self.tableView.widthAnchor constraintEqualToAnchor:self.widthAnchor]
    ]];
}

- (UITableView *)tableView {
    if (!self->_tableView) {
        self->_tableView = [[AutosizingTableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
        self->_tableView.translatesAutoresizingMaskIntoConstraints = NO;
        self->_tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
        self->_tableView.rowHeight = UITableViewAutomaticDimension;
        self->_tableView.estimatedRowHeight = UITableViewAutomaticDimension;
        self->_tableView.allowsSelection = NO;
        self->_tableView.scrollEnabled = NO;
        self->_tableView.delegate = self;
        self->_tableView.dataSource = self;
        [self->_tableView registerClass:[MyTableViewCell class] forCellReuseIdentifier:@"myTableViewCell"];
    }
    return self->_tableView;
}

- (void)setdata:(NSArray<MyData *> *)data {
    self->_data = data;
    [self.tableView reloadData];
}

#pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return self.data.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"myTableViewCell" forIndexPath:indexPath];
    MyData *data = self.data[indexPath.row];
    cell.detail = detail;
    return cell;
}

@end

AutosizingTableView

如上一节所述,这只是为了使表视图自动调整大小.没有这个,表视图的高度为零,并保持为零,因为 tableView:cellForRowAtIndexPath:方法从未因为表视图的高度而被调用.

AutosizingTableView

As was mentioned in the previous section, this is just to make it so the table view autosizes. Without this, the table view height was zero and stayed at zero since the tableView:cellForRowAtIndexPath: method was never getting called because of the table view height.

@implementation AutosizingTableView

- (CGSize)intrinsicContentSize {
    return self.contentSize;
}

- (void)setContentSize:(CGSize)contentSize {
    [super setContentSize:contentSize];
    [self invalidateIntrinsicContentSize];
}

@end

推荐答案

尝试一下:

- (void)initialize {
[self.contentView setBackgroundColor:[UIColor systemTealColor]];
[self.backgroundView setBackgroundColor:[UIColor systemGrayColor]];

[self.contentView addSubview:self.firstLabel];
[self.contentView addSubview:self.secondLabel];

NSLayoutConstraint *heightConstraint = [self.heightAnchor constraintEqualToConstant:1.0f];
[heightConstraint setPriority:50];

[NSLayoutConstraint activateConstraints:@[
    [self.firstLabel.leadingAnchor constraintEqualToAnchor:self.contentView.layoutMarginsGuide.leadingAnchor],
    [self.firstLabel.topAnchor constraintEqualToAnchor:self.contentView.layoutMarginsGuide.topAnchor],
    [self.firstLabel.trailingAnchor constraintEqualToAnchor:self.centerXAnchor constant:-4.0f],
    
    [self.secondLabel.leadingAnchor constraintEqualToAnchor:self.centerXAnchor constant:4.0f],
    [self.secondLabel.topAnchor constraintEqualToAnchor:self.contentView.layoutMarginsGuide.topAnchor],
    [self.secondLabel.trailingAnchor constraintEqualToAnchor:self.contentView.layoutMarginsGuide.trailingAnchor],
    
    [self.contentView.layoutMarginsGuide.bottomAnchor constraintGreaterThanOrEqualToAnchor:self.firstLabel.bottomAnchor constant:20.0f],
    [self.contentView.layoutMarginsGuide.bottomAnchor constraintGreaterThanOrEqualToAnchor:self.secondLabel.bottomAnchor constant:20.0f],
    
    heightConstraint
]];
}

您应该将标签添加到contentView中,而不要直接添加单元格.

You should be adding the labels to the contentView and no the cell directly.

这篇关于UITableViewCell无法自动调整大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆