在弹出一个视图控制器后,UITableViewController表现奇怪

9
我的UITableView有许多可重用的单元格,当我点击其中一个单元格时,它会通过推送转场带我到另一个视图控制器(显示该单元格的详细信息,比如商品名称、价格、图片等等)。当我弹出该视图控制器(通过点击返回按钮)时,UITableView表现出奇怪的行为:
a) 如果滚动到底部,它将自动向上滚动一点(大约50个点),留下最后一个单元格几乎不可见,所以我必须再次向下滚动。我的每个单元格高度都是60个点。
b) 滚动条总是显示然后消失,表明某些东西正在移动UITableView(尽管如果没有滚动到底部,内容就不会自动移动)。
这种情况发生在我应用程序中的多个UITableView中。我没有在viewWillAppear中强制重新加载表视图,所以我不明白发生了什么。我的内容在从服务器加载后是静态的(除非用户更改它,然后执行重新加载)。但只是显示一个项目的详情并弹出那个VC不会改变表视图中的任何内容。
编辑:好吧,我已经找到了问题所在:我在推送该segue时隐藏了一个UIToolbar。如果我始终让它可见(这不是我想要的),它仍然会在我的表视图中弹出滚动条动画,但如果在最后几行,则不会滚动表视图。
6个回答

7

将以下内容添加到viewDidLoad中。

self.automaticallyAdjustsScrollViewInsets = NO;

这解决了我在导航回视图控制器后表视图下移的问题。

3
我已经成功解决了第一个问题。似乎tableview没有考虑到44个像素的UIToolbar。在prepareForSegue中保存tableview的偏移量(用CGPoint属性保存)。
self.tableViewScrollOffset = self.tableView.contentOffset;

然后,在viewWillAppear:中,检查它是否已被修改。如果是,则恢复它。
if(self.tableView.contentOffset.y != self.tableViewScrollOffset.y) {
        [self.tableView setContentOffset:self.tableViewScrollOffset];
        self.tableViewScrollOffset = CGPointZero;
    }

你能否更详细地解释一下为什么会发生这种情况?或者有其他人可以解释一下吗? - Krtko
太棒了...解决了类似的问题...问题在于,每当您从视图控制器返回时,表格视图的滚动偏移量会相应地更改。因此,您需要在prePareForSegue:方法中(即导航之前)将contentoffset值捕获到一个属性中,然后在同一类中的viewWillAppear:方法中进行检查。如果它已更改,则将scrolloffset属性值设置为零。 - Vinayak Hejib

3
这确实是iOS 8.x中的一个bug。
到目前为止,所有给出的答案都不能真正解决这个问题。问题在于,当表格被重新绘制时(例如当视图被推送时),iOS会忘记(或不考虑)先前计算的单元格大小。解决此问题的一种方法可以在这里找到:UITableView layout messing up on push segue and return. (iOS 8, Xcode beta 5, Swift) (所以这个问题甚至是重复的)。
然而,那里提供的解决方案过于复杂,并且在某些情况下缓存将失败(例如,UIContentSizeCategoryDidChangeNotification未被考虑)。
但是,有一个非常简单的解决方案,尽管它很奇怪:
如果您在didSelectRowAtIndexPath中使用手动performSequeWithIdentifier,只需在之前添加[self.tableView reloadData]
如果您正在使用来自单元格的IB seque,则只需在prepareForSeque代码中添加[self.tableView reloadData]
这个解决方案之所以有效,是因为它将强制iOS重新估算可见单元格,因此它不再将内容滚动到另一个位置。幸运的是,在这里tableView reloadData的开销并不太大,因为只有可见单元格将被重新估算。

0

有一种可能,你有一个流氓的 scrollToRowAtIndexPath:atScrollPosition:animated 挂在那里吗?


不,我在Xcode中搜索了整个项目,没有代码行弹出。 - swiftcode

0

我也遇到了这个问题。我设法找到了原因。在我的情况下,表格视图标题高度是基于文本计算的,由于文本高度为负,因此即使内容插入和滚动插入为零,表格视图也会向下移动。

这只发生在第一次。下一次它会计算正确。我发现一个奇怪的事情是,当A类(具有表格视图)从init推出另一个B类时,当B类的键盘打开时,Class A的viewDidLoad被调用,并且在B类从导航控制器中卸载之前,表格视图将重新加载A类。


0

将automaticallyAdjustsScrollViewInsets设置为上述建议未起作用,缓存和设置tableViewScrollOffset也未奏效。

因此,我想出了一个解决方法,对我非常有效。

解决方法是添加一个高度为1px,宽度为320px的虚拟UIView,并将其放置在“顶部布局指南”和UITableView之间。该视图的背景可以设置为透明,使其不可见。

现在使用Autolayouts,将“虚拟视图”的顶部固定在Top上。然后,将tableview的顶部约束与虚拟视图相关联。发现这解决了tableview位置错误的问题。

提供了虚拟视图的屏幕截图以及自动布局约束,方便参考。虚拟视图已设置为更大的高度和红色背景颜色,仅用于说明目的。

enter image description here


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