我在我的项目中实施聊天。我开始使用smileyborg的方法 - 使用动态表格单元格的自动布局(example is here,SO 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];
}
答案 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上与单元格中其他对象相关的压缩阻力优先级。