UITextView 在 UITableViewCell 中的自动布局 iOS 6 和 iOS 7 的区别。

3
我正在编写一个应用程序并创建消息界面。目前,该界面是一个包含我的自定义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 这是iOS 6中的实际效果: iOS 6 下面是我想要在iOS 7中实现的预期行为:iOS 7 需要注意的是,实际表格视图单元格的高度似乎是正确的,但是文本视图没有相应地调整,尽管可以这样做。我已经尝试过以上两种方法,并尝试了不同的技术,但都没有成功。我相当确信我需要使用`removeFromSuperview`,因为这是同时使用自动布局和适应我的尝试所必需的唯一方式。在下列情况下,交付/已读标签将被移除:
  • 消息线程中有两个人
  • 该消息是该线程中的最新消息
  • 最后一条消息是你发出的
我知道这是一个非常具体的问题,但如果有人有对此原因的想法,我将不胜感激。请注意,文本视图是不可编辑的,但是可以选择。另外,编辑:我有时也会让iOS 6抛出`-[UITableViewCell layoutSublayersOfLayer:]`的断言失败,即使我的自定义子类没有实现该函数。它之前曾经因约束而发出警告,但这是个不确定的错误。
1个回答

1
我解决了这个问题,只需要一直在单元格上保留两个UILabel。我会巧妙地安排日期和阅读次数。如果将来有人遇到类似的问题,我会留下这个解决方案。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接