Autolayout + UITableView在iOS 6上生成幻像节标题

时间:2014-02-21 14:01:49

标签: ios uitableview ios6 autolayout

所以我继承了一个包含一些代码的项目,这种行为类似于iMessage。

enter image description here

这里有两个视图,最上面一个是从导航栏到撰写邮件一个,另一个是底部的撰写邮件。

当输入的文本跨越多行时,撰写消息的高度应该增加,所以在显示键盘时,在容器视图上设置了以下自动布局规则:

 NSDictionary *viewsToConstrain = NSDictionaryOfVariableBindings(bottomView, topView);
    _vConstraints = [NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:@"V:|[topView]-(0)-[bottomView]-(==%.1f)-|", keyboardHeight]
                                                            options:NSLayoutFormatAlignAllCenterX
                                                            metrics:nil
                                                              views:viewsToConstrain];

因此,当您在该撰写文本视图中键入时,撰写框会变得更大,并且包含消息的tableView会变得更小,如下所示:

enter image description here

每当您单击“发送”按钮时,都会创建一个Message实体并将其存储在CoreData中。承载表视图和撰写消息视图的视图控制器有一个获取结果控制器,它使用一些标准的UITableView动画将新创建的消息添加到表视图中:

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
        [self.tableView beginUpdates];
}

- (void)controller:(NSFetchedResultsController *)controller
   didChangeObject:(id)anObject
       atIndexPath:(NSIndexPath *)indexPath
     forChangeType:(NSFetchedResultsChangeType)type
      newIndexPath:(NSIndexPath *)newIndexPath
{

        switch (type)
        {
            case NSFetchedResultsChangeInsert:

                    [self.tableView insertRowsAtIndexPaths:@[newIndexPath]
                                          withRowAnimation:UITableViewRowAnimationTop];

                break;

                ...
                // Handle all the other cases
        }
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
    [self.tableView endUpdates];
}

一切正常。 现在,只要消息足够长,撰写视图就会变得很高,以至于表视图的高度变为0。

enter image description here

每当在此状态下按下发送按钮时,

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
调用表视图上的

方法并添加新标题,即使

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

方法返回正确数量的标题(在本例中为1),并添加第二个标题,即使它不应该存在。

enter image description here

正如您所看到的,它实际上位于其中一个单元格的顶部,并且部分遮挡了该单元格。

并且它的行为并不像标题,因为它不会推开顶部标题,而是在它之下,如下所示:

enter image description here

这真的很奇怪,因为只要桌面视图的高度没有达到0就可以正常工作,即使这样,它也可以在iOS 7上运行。

如果我删除了动画,删除beginUpdates endUpdates并将insertRowsAtIndexPaths:withRowAnimation:替换为reloadData - 这一切在iOS 6上也可以。

所以底线:使用autolayout使tableView更小以某种方式使它认为它应该有更多的部分,它不会回收旧的部分标题视图并插入一个不像行为的幻像标题节标题,不应插入其中。

我在iOS6上实现了我的解决方案,iOS 7工作正常,但我真的很想知道为什么会这样。

有什么想法吗?

编辑:

以下是viewForHeaderInSection

的实施方式
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    UITableViewHeaderFooterView *view = [tableView dequeueReusableHeaderFooterViewWithIdentifier:kSectionHeaderXibIdentifier];
    UILabel *textLabel = (UILabel *)[view viewWithTag:kSectionHeaderTextTag];
    if (!textLabel)
    {
        // we have no subviews yet, so create them

        view.contentView.backgroundColor = [UIColor whiteColor];

        textLabel = [UILabel autoLayoutView];
        textLabel.tag = kSectionHeaderTextTag;
        textLabel.backgroundColor = [UIColor clearColor];
        [view.contentView addSubview:textLabel];

        UIView *leftArt = [UIView autoLayoutView];
        leftArt.backgroundColor = kSectionOrnamentColor;
        [view.contentView addSubview:leftArt];

        UIView *rightArt = [UIView autoLayoutView];
        rightArt.backgroundColor = kSectionOrnamentColor;
        [view.contentView addSubview:rightArt];

        NSDictionary *bindingViews = NSDictionaryOfVariableBindings(textLabel, leftArt, rightArt);

        NSString *horzFormat = @"H:|-(12)-[leftArt(>=0)]-(8)-[textLabel]-(8)-[rightArt(leftArt)]-(12)-|";
        [view.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:horzFormat
                                                                                options:0
                                                                                metrics:nil
                                                                                  views:bindingViews]];

        [view.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(28.)-[leftArt(1)]-(>=0)-|"
                                                                                 options:0 metrics:nil views:bindingViews]];

        [textLabel pinToSuperviewEdges:JRTViewPinTopEdge inset:14.];
        [rightArt pinAttribute:NSLayoutAttributeTop toSameAttributeOfView:leftArt];
        [rightArt pinAttribute:NSLayoutAttributeHeight toSameAttributeOfView:leftArt];
    }

    textLabel.attributedText = [self titleForHeaderInSection:section];

    [textLabel invalidateIntrinsicContentSize];
    [view.contentView needsUpdateConstraints];

    return view;
}

我们获取默认标题视图并在其上添加一些子视图。

0 个答案:

没有答案