UITableViewCell中的UITextView无法满足约束

时间:2014-05-10 17:59:21

标签: ios objective-c uitableview uitextview autolayout

我在我的项目中实施聊天。我开始使用smileyborg的方法 - 使用动态表格单元格的自动布局(example is hereSO post is here)。但现在我必须使用UITextView来显示聊天消息,因为我必须检测URL,在文本中插入微笑图像并检测文本中用户昵称的触摸,而且我知道UILabel类型的类都不支持所有这些内容。

问题是如果我使用相同的代码,UITextView不会自动正确调整大小。它确实调整了大小,但我得到了很多类似的警告:

"<NSLayoutConstraint:0x173cea60 V:[GGTextView:0xad34600(60)]>",
"<NSLayoutConstraint:0x172e8a10 V:[GGTextView:0xad34600]-(0)-|   (Names: '|':UITableViewCellContentView:0x172e43d0 )>",
"<NSAutoresizingMaskLayoutConstraint:0x173cee80 h=--& v=--& V:[UITableViewCellContentView:0x172e43d0(82)]>",
"<NSLayoutConstraint:0x172e8990 V:|-(0)-[GGTextView:0xad34600]   (Names: '|':UITableViewCellContentView:0x172e43d0 )>"

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x173cea60 V:[GGTextView:0xad34600(60)]>

我该如何正确地做到这一点?这是我的代码

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

// Setup offscreen cell to calculate height

id chatObject = [self.messages objectAtIndex:indexPath.row];
GGTableViewCell *cell = [self setupOffscreenMessageCellWithMessage:chatObject];

[cell setNeedsUpdateConstraints];
[cell updateConstraintsIfNeeded];

cell.bounds = CGRectMake(0.0f, 0.0f, CGRectGetWidth(tableView.bounds), CGRectGetHeight(cell.bounds));

[cell setNeedsLayout];
[cell layoutIfNeeded];

// Get the actual height required for the cell's contentView
CGFloat height = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;

// Add an extra point to the height to account for the cell separator, which is added between the bottom
// of the cell's contentView and the bottom of the table view cell.
height += 1.0f;

return height;
}

TableViewCell代码:

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {

    [self layoutSubviews];
}
return self;
}

- (void)layoutSubviews {  

[super layoutSubviews];
[self.contentView setNeedsLayout];
[self.contentView layoutIfNeeded];
}

- (void)setupWithMessage:(ChatMessage*)message {
   // ... setting up attributed string here    

self.messageTextView.attributedText = messageText;

[self setNeedsUpdateConstraints];
[self updateConstraintsIfNeeded];
}

最后我的UITextView子类的代码根据内容高度创建高度约束:

@implementation GGTextView

- (void)layoutSubviews
{
    [super layoutSubviews];

    [self setNeedsUpdateConstraints];
}

- (void)updateConstraints
{
    CGSize size = [self sizeThatFits:CGSizeMake(self.bounds.size.width, FLT_MAX)];

    if (!self.heightConstraint) {
        self.heightConstraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:0 multiplier:1.0f constant:size.height];
        [self addConstraint:self.heightConstraint];
    }

    self.heightConstraint.constant = size.height;
    [super updateConstraints];
}

3 个答案:

答案 0 :(得分:0)

您是使用界面构建器还是从代码实例化视图?如果您正在使用IB,则可以增加要快速保留的约束的优先级,并降低在调整视图大小时可以调整的约束的优先级。另外,尝试设置可以调整为&gt; =或&lt; =约束的那些,并且当事情调整大小时应该使警告静音。

答案 1 :(得分:0)

使用自定义UITextView设置高度约束并使用灵活高度UITableViewCell,我遇到了同样的问题。我发现UITextViews通常与systemLayoutFittingSize不兼容,即使使用自定义高度约束来充当它intrinsicContentSize。大多数情况下,它只是返回错误的高度并且弄乱了UITableViewCell的自动调整约束。

我发现的唯一解决方案是不使用自定义文本视图(带约束)并手动计算单元格的高度。您的UITextView应该具有对其超级视图的边缘的约束。为了计算UITextView的高度,我添加了textView内容并使用了

CGFloat textViewHeight = [textView sizeThatFits:CGSizeMake(textView.frame.size.width, CGFLOAT_MAX)].height

由此,你应该能够计算出细胞高度的其余部分。

答案 2 :(得分:0)

您可以尝试更改UITextView上与单元格中其他对象相关的压缩阻力优先级。