【问题标题】:UITableView contentSizeUITableView 内容大小
【发布时间】:2012-10-22 07:23:24
【问题描述】:

我的应用中的几个表格视图出现问题。

当表格的内容发生变化(因此表格视图的内容变大)时,就会出现问题。

由于某种原因,UITableView 的 contentSize 保持不变,这意味着我无法滚动查看新内容。

当特定单元格变大时(在 [tableView reloadData]; 之后)或当我添加新单元格(使用 NSFetchedResultsController 委托方法)时,会发生这种情况。

我需要为 tableView 做些什么来重新调整它的 contentSize 吗?

编辑以显示代码,但这只是样板 NSFetchedResultsController 委托代码...

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
    // The fetch controller is about to start sending change notifications, so prepare the table view for updates.
    [self.tableView beginUpdates];
}


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

    UITableView *tableView = self.tableView;

    switch(type) {

        case NSFetchedResultsChangeInsert:
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeUpdate:
            [self configureCell:(OJFPunchListCell*)[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
            break;

        case NSFetchedResultsChangeMove:
            [tableView deleteRowsAtIndexPaths:[NSArray
                                           arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            [tableView insertRowsAtIndexPaths:[NSArray
                                           arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}


- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id )sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {

    switch(type) {

        case NSFetchedResultsChangeInsert:
            [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}


- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
    // The fetch controller has sent all current change notifications, so tell the table view to process all updates.
    [self.tableView endUpdates];
}

我以前在 iOS5 中做过这种事情,从来没有遇到过问题。似乎这可能是 iOS6 的变化?

::编辑::

关于这一点的愚蠢之处在于,我在同一个应用程序中有许多其他 UITableViewControllers,它们都工作正常。我可以添加新单元格、添加动态大小的单元格、调整单元格大小等...并且表格都可以正确滚动所有内容。

这个问题现在出现在我最近添加的几个 tableview 上。

::编辑::

好的,只是做一些调试。当我第一次进入表格视图时,contentSize.height 是 594。

当我添加一个新项目并返回到同一个 tableviewController 时,contentSize.height 为 749。

但是,我无法滚动查看 tableView 底部新添加的单元格。它只是不会在那里滚动。它在旧的 contentSize 高度反弹。

【问题讨论】:

  • 如果您为heightForRow:atIndexPath: 中的单元格提供正确的高度应该没问题。当单元格应该变大时,您是否更新了高度?
  • 我在添加单元格时不需要修改内容大小。你使用什么方法?插入行?你能显示一些代码吗?
  • 是的,随着实际单元格变大,我正在正确设置高度。但是表格视图的底部不会滚动到单元格变大的数量。即如果单元格变大 50 点,那么我无法滚动查看单元格的底部 50 点。另外,我要添加新单元格的表格,所有单元格的大小都相同,只是更多。 (就像主细节模型一样,主表视图有一个 + 按钮可以推送到控制器以创建一个新项目,然后显示在主视图中)新单元格在那里,但滚动视图弹跳,所以我看不到它。
  • 如果 contentSize 值是正确的并且表格框架是正确的,那么也许 contentInset 是原因?
  • 检查tableView:heightForRowAtIndexPath:,在我的例子中这个方法返回负值。

标签: iphone ios uitableview nsfetchedresultscontroller


【解决方案1】:

我遇到了同样的问题,最终得到了这个解决方法。我在[self.tableView endUpdates]; 之后设置contentSize

[self.tableView endUpdates];

NSLog(@"%f", self.tableView.contentSize.height);

self.tableView.contentSize = [self.tableView sizeThatFits:CGSizeMake(CGRectGetWidth(self.tableView.bounds), CGFLOAT_MAX)];

NSLog(@"%f", self.tableView.contentSize.height);

[self.tableView setContentInset:UIEdgeInsetsMake(50, 0, -50, 0)];

【讨论】:

  • 很好,这也适用于我。我想知道为什么 Apple 在 table-view 完成重新加载时不提供委托调用。
【解决方案2】:

我在使用带有两个子 VC 的自定义视图控制器时遇到了同样的问题,一个是 tableview + fetched results controller。

我会在从一个 vc 添加内容并返回我的表格后,我将无法滚动到底部的新内容。

因此,在我的 tableview + fetched results 控制器中,我根据我拥有的已获取对象的数量调整内容大小,无论它们来自何处。

最坏的情况是我在展示VC的时候没有添加任何内容,但是成本很低。

//In my tableview + fetched results controller class
-(void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];


    NSUInteger objCount = self.fetchedResultsController.fetchedObjects.count;
    //My custom cell has a height of 50.0f, yours may not!
    CGFloat tableHeight = objCount * 50.0f;

    NSLog(@"%i objects, total height: %f",objCount,tableHeight);

    [self.tableView setContentSize:CGSizeMake(self.tableView.contentSize.width, tableHeight)];

}

【讨论】:

    【解决方案3】:

    我有带有“UITableViewAutomaticDimension”的动态表格视图。在重新加载后发生了一些事情,它的内容大小等于它的帧大小。在我手动将内容大小设置为表格边界大小后,一切正常。我希望这会有所帮助。

    table.beginUpdates()
    table.contentSize = CGSize(width: table.bounds.width, height: table.bounds.height)
    table.endUpdates()
    

    这是在我完成 table.reloadData() 之后

    【讨论】:

      【解决方案4】:

      试试这个:

      我遇到了类似的问题。在我的情况下,我将一个 tableview 拖到一个自定义视图控制器,它由一个 push segue 呈现。如果 tableview 中显示的数据量超过某个数字,那么我不能触摸表格视图底部的单元格。

      已经尝试了很多方法:设置表格视图的框架/内容大小,但没有一个适合我。最后,我找到了根本原因并以简单的方式解决了它(虽然不优雅)。

      首先,根本原因:IB创建的表格视图的宽度大于其父视图控制器。因此,任何超出视图边界的单元格都不会被触摸。

      所以,解决方法很简单:进入 StoryBoard,调整 table view 的宽度,使其小于父 view 的宽度。似乎如果一个 table view 是由 StoryBoard 创建的,你不能改变它的框架通过代码。这就是我到目前为止所发现的。我猜这是 StoryBoard 的错误。

      希望对你有用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-04-29
        • 2019-07-18
        • 2019-06-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-05
        相关资源
        最近更新 更多