我正在编写一个应用程序并创建消息界面。目前,该界面是一个包含我的自定义
现在,使用自动布局结合视图控制器上的
我猜从其父视图中删除视图是主要的罪魁祸首,但我不明白为什么这只会发生在iOS 6上而不是在6和7上都发生。
现在,给您代码。以下是我的
以下是我在Interface Builder中设置的约束条件。请注意消息文本视图的静态宽度:
这是iOS 6中的实际效果:
下面是我想要在iOS 7中实现的预期行为:
需要注意的是,实际表格视图单元格的高度似乎是正确的,但是文本视图没有相应地调整,尽管可以这样做。我已经尝试过以上两种方法,并尝试了不同的技术,但都没有成功。我相当确信我需要使用`removeFromSuperview`,因为这是同时使用自动布局和适应我的尝试所必需的唯一方式。在下列情况下,交付/已读标签将被移除:
UITableViewCell
子类单元格的UITableView
。我使用接口生成器中的约束条件使用自动布局。我的消息很像默认的消息应用程序。每个表格视图单元格有三个主要部分:一个包含消息正文的UITextView
和两个额外的UILabel
,一个用于发件人的名称和/或时间戳,另一个用于传递/已读收据。现在,使用自动布局结合视图控制器上的
tableView:heightForRowAtIndexPath:
,每个表格视图单元格中的消息文本视图都应根据消息的大小增长(目前我使用sizeWithFont:constainedToSize:lineBreakMode
-我知道它已被弃用,但替代品在iOS 6上不起作用,并且到目前为止也不够稳定)。当所有标签和文本视图都存在于UI上时,这运行良好。但是,在单个消息线程中,我使用removeFromSuperview
删除了所有消息单元格的传递/已读标签,但最终的消息除外(如果此最终消息由您发送)。这不会对iOS 7产生不利影响,但是在iOS 6上,任何已删除标签的单元格都会导致文本视图的高度为0.0
(通过调试输出确认)。编程重新添加标签和适当的自动布局约束似乎可以解决此问题,但在删除该标签的任何单元格中,即使我计算了tableView:heightForRowAtIndexPath:
中文本视图的正高度,文本视图高度也为零,剩余的标签最终会向上移动以“覆盖”文本视图。我猜从其父视图中删除视图是主要的罪魁祸首,但我不明白为什么这只会发生在iOS 6上而不是在6和7上都发生。
现在,给您代码。以下是我的
cellForRowAtIndexPath:
和heightForRowAtIndexPath:
方法。- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString * sentMessageCellIdentifier = @"sentMessageCell";
static NSString * receivedMessageCellIdentifier = @"receivedMessageCell";
MessageCell * cell;
Message * messageObject = [associatedThread.messages objectAtIndex:indexPath.row];
GroupMember * selfMm = [associatedThread.parentGroup groupMemberForUser:[ApplicationInstance getInstance].currentUser];
if ([messageObject.sender isEqualToGroupMember:selfMm]) {
// Sent
cell = (MessageCell *) [tableView dequeueReusableCellWithIdentifier:sentMessageCellIdentifier];
cell.sentTimeLabel.text = [UtilityFunctions messageFriendlyFormattedDateTimeForDate:messageObject.messageTime];
if ([messageObject isEqualToMessage:[associatedThread.messages lastObject]]) {
cell.deliveredReadByLabel.text = @"Sent";
} else {
cell.deliveredReadByLabel.text = nil;
}
} else {
// Received
cell = (MessageCell *) [tableView dequeueReusableCellWithIdentifier:receivedMessageCellIdentifier];
[cell setSenderAndDateTimeForSender:messageObject.sender date:messageObject.messageTime];
}
// Read by label
NSString * readByText = nil;
if (associatedThread.parentGroupMember == nil) {
// Group thread
if (messageObject.readBy.count == 0) {
if (![messageObject.sender isEqualToGroupMember:selfMm]) {
readByText = @"Read by: only you";
}
} else {
NSInteger readByCount = messageObject.readBy.count;
NSInteger toSubtract = [messageObject.sender isEqualToGroupMember:selfMm] ? 1 : 2;
if (readByCount == associatedThread.members.count - toSubtract) { // If everyone read it (minus you and the sender)
readByText = @"Read by everyone";
} else {
GroupMember * randRbm = [messageObject.readBy firstObject];
if (messageObject.readBy.count == 1) {
cell.deliveredReadByLabel.text = [NSString stringWithFormat:@"Read by: %@", randRbm.user.displayName];
} else if (messageObject.readBy.count > 1) {
cell.deliveredReadByLabel.text = [NSString stringWithFormat:@"Read by: %@ + %d", randRbm.user.displayName, messageObject.readBy.count - 1];
}
cell.deliveredReadByLabel.userInteractionEnabled = YES;
[cell.deliveredReadByLabel addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapReadByLabel:)]];
}
}
} else {
// One-on-one individual thread
if ([messageObject isEqualToMessage:[associatedThread.messages lastObject]] &&
[messageObject.sender isEqualToGroupMember:selfMm]) {
if (cell.deliveredReadByLabel.superview == nil) {
[cell.contentView addSubview:cell.deliveredReadByLabel];
// Auto-layout bindings
NSArray * constaints = @[[NSLayoutConstraint constraintWithItem:cell.deliveredReadByLabel
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:cell.sentTimeLabel
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:1.0],
[NSLayoutConstraint constraintWithItem:cell.deliveredReadByLabel
attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationEqual
toItem:cell.contentView
attribute:NSLayoutAttributeLeft
multiplier:1.0
constant:20.0],
[NSLayoutConstraint constraintWithItem:cell.deliveredReadByLabel
attribute:NSLayoutAttributeRight
relatedBy:NSLayoutRelationEqual
toItem:cell.contentView
attribute:NSLayoutAttributeRight
multiplier:1.0
constant:-20.0],
[NSLayoutConstraint constraintWithItem:cell.deliveredReadByLabel
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:cell.contentView
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:-5.0]
];
[cell addConstraints:constaints];
}
if (messageObject.readBy.count == 1) {
readByText = @"Read";
}
} else {
[cell.deliveredReadByLabel removeFromSuperview];
}
}
if (readByText != nil) {
cell.deliveredReadByLabel.text = readByText;
}
debugLog(@"%@", [messageObject isEqualToMessage:[associatedThread.messages lastObject]] ? @"YES" : @"NO");
debugLog(@"x,y [%f, %f] | w,h [%f, %f] - message view", cell.messageView.frame.origin.x, cell.messageView.frame.origin.y, cell.messageView.frame.size.width, cell.messageView.frame.size.height);
debugLog(@"x,y [%f, %f] | w,h [%f, %f] - sent time label", cell.sentTimeLabel.frame.origin.x, cell.sentTimeLabel.frame.origin.y, cell.sentTimeLabel.frame.size.width, cell.sentTimeLabel.frame.size.height);
debugLog(@"x,y [%f, %f] | w,h [%f, %f] - sender time label", cell.senderAndDateTimeLabel.frame.origin.x, cell.senderAndDateTimeLabel.frame.origin.y, cell.senderAndDateTimeLabel.frame.size.width, cell.senderAndDateTimeLabel.frame.size.height);
debugLog(@"x,y [%f, %f] | w,h [%f, %f] - delivered label", cell.deliveredReadByLabel.frame.origin.x, cell.deliveredReadByLabel.frame.origin.y, cell.deliveredReadByLabel.frame.size.width, cell.deliveredReadByLabel.frame.size.height);
// Message body
[UtilityFunctions setZeroInsetsForTextView:cell.messageView];
cell.messageView.text = messageObject.messageBody;
cell.messageView.scrollEnabled = YES;
cell.messageView.scrollEnabled = NO;
return cell;
}
- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *) indexPath {
CGFloat totalHeight = 0.0;
Message * m = [associatedThread.messages objectAtIndex:indexPath.row];
// Top and bottom padding
totalHeight += 5.0 + 5.0;
// Height + padding between labels (and text view)
totalHeight += 14.0 + 14.0 + 1.0 + 1.0; // height + height + padding + padding
// Modify UI slightly if incoming message and one-on-one thread:
if (associatedThread.parentGroupMember != nil) {
totalHeight -= (14.0 + 1.0);
if ([m isEqualToMessage:[associatedThread.messages lastObject]]) {
if ([m.sender isEqualToGroupMember:[associatedThread.parentGroup groupMemberForUser:[ApplicationInstance getInstance].currentUser]]) {
totalHeight += (14.0 + 1.0);
}
}
}
NSString * bodyText = m.messageBody;
CGSize constraint = CGSizeMake(MESSAGE_TEXT_WIDTH_MAX, CGFLOAT_MAX);
CGSize sizeWithFont = [bodyText sizeWithFont:[UIFont systemFontOfSize:16.0] constrainedToSize:constraint lineBreakMode:NSLineBreakByWordWrapping];
totalHeight += sizeWithFont.height + 1.0; // 1.0 because iOS hates me
if ([m isEqualToMessage:[associatedThread.messages lastObject]]) {
debugLog(@"YES");
} else {
debugLog(@"NO");
}
debugLog(@"height: %f", totalHeight);
return totalHeight;
}
以下是我在Interface Builder中设置的约束条件。请注意消息文本视图的静态宽度:
![Auto layout constraints](https://i.imgur.com/N0woS89.png)
![iOS 6](https://i.imgur.com/P4BWX41.png)
![iOS 7](https://i.imgur.com/lB51fF4.png)
- 消息线程中有两个人
- 该消息是该线程中的最新消息
- 最后一条消息是你发出的