问题
I am trying to create a chat application where in I have made a custom UITableViewCell using only code. So it is like a bubble with Name, message and time labels inside the bubble in the same order. The name label should be half of the total bubble's width and the bubble's width is determined by the width of the message whose maximum width is 220.0f after which it will go to next line.
The problem that I am facing is: I am trying to change the name label's width constraint's constant according to the message width. But since iOS reuses the cell, when I scroll my UITableView some of the name label's width gets messed up. It tries to use the old width and therefore, the name label gets out of the bubble if name is big enough.
I am attaching some images to demonstrate that:
Correct width of Name Label http://postimg.org/image/yd6z2jdft/c1f192cd/
Wrong width of Name label because of scroll http://postimg.org/image/u0m7pc8uh/cd7ea4ea/
Here is the code I am using. I am posting only the relevant part
cellforrowatindexpath:
chatCell = (ChatTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"chatSend"];
if (chatCell == nil)
{
chatCell = [[ChatTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"chatSend"];
}
chatCell.chatMessageLabel.text = message.getMessage;
chatCell.chatNameLabel.text = message.getFromName;
chatCell.chatTimeLabel.text = [dateFormatter stringFromDate:messageDateTime];
[chatCell setChatNameLabelWidth:Messagesize.width];
Heightforrowatindexpath:
Messagesize = [message.getMessage boundingRectWithSize:CGSizeMake(220.0f, CGFLOAT_MAX)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{NSFontAttributeName:[UIFont boldSystemFontOfSize:14]}
context:nil].size;
ChatTableViewCell.m
in class extension
@property (nonatomic, strong) NSLayoutConstraint *chatNameLabelWidthConstraint;
init method
horizontal = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-16-[chatNameLabel]" options:NSLayoutFormatDirectionLeftToRight metrics:nil views:NSDictionaryOfVariableBindings(chatNameLabel)];
[Main addConstraints:horizontal];
// ////////////////////////////////////////////////////////////////////////////////////////////
//Setting width constraint for chatNameLabel
chatNameLabelWidthConstraint = [NSLayoutConstraint constraintWithItem:chatNameLabel attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.f constant:64.0f];
[chatNameLabel addConstraint:chatNameLabelWidthConstraint];
// ////////////////////////////////////////////////////////////////////////////////////////////
//Setting the constraints for chatNameLabel. It should be at 16 distance from right and left of superview, i.e., Main and 8 distance from top and chatMessageLabel which is at 8 distance from chatTimeLabel which is at 8 distance from bottom of superview.
vertical = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-8-[chatNameLabel]-8-[chatMessageLabel]-8-[chatTimeLabel]-8-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(chatNameLabel,chatMessageLabel,chatTimeLabel)];
[Main addConstraints:vertical];
Another method to set width
- (void)setChatNameLabelWidth:(CGFloat) messageWidth
{
CGFloat chatNameLabelWidth;
if((messageWidth + 32.0f)<128.0f)
{
chatNameLabelWidth = 64.0f;
}
else
{
chatNameLabelWidth = (messageWidth + 32.0f)/2;
}
chatNameLabelWidthConstraint.constant = chatNameLabelWidth;
[chatNameLabel layoutIfNeeded];
}
回答1:
Finally, I solved it using proportional width. If constraint is used, it will surely get messed up but using proportional width along with content hugging and content compression resistance priorities, should solve the problem easily:
This is how I did it:
NSLayoutConstraint *proportionalWidth = [NSLayoutConstraint constraintWithItem:chatNameLabel
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:Main
attribute:NSLayoutAttributeWidth
multiplier:.5
constant:0];
proportionalWidth.priority = 750;
[Main addConstraint:proportionalWidth];
[chatNameLabel setContentCompressionResistancePriority:250 forAxis:UILayoutConstraintAxisHorizontal];
来源:https://stackoverflow.com/questions/32435425/changing-uitableviewcells-width-constraints-constant-value-for-each-instance