当 UITableViewController frame.height 较小时,UITableViewController refreshControl 出现故障
UITableViewController refreshControl is glitchy when UITableViewController frame.height is small
我遇到一个问题,原因是当 UITableViewController 的框架低于特定高度时,UITableViewController refreshControl 会出现故障。
就目前而言,我有一个 UIViewController,在其中我有一个嵌入了 UITableViewController 的 ContainerView。我希望高度为屏幕的 50%。
当我使用 refreshControl 时,出现这种行为:The tableView jumps down at the very end when scrolling down. You'll notice it towards the end of this video when I decide to scroll down slowly.
当ContainerView frame 高于某个值时,不会出现此问题。因此,当高度为屏幕的 75% 时,一切正常,refreshControl 也很流畅。当它是 50% 时,就会出现该错误。
我尝试了两种不同的方法:
self.tableView.frame = CGRectMake(0, numOfPixelsToDropTableBy, self.tableView.frame.size.width, self.tableView.frame.size.height)
是我尝试过的一件事。这样做的问题是,如果您想通过 ContainerView 为 tableView 提供圆角,而您的 ContainerView 仍然占用更多 space 的事实,这会使其他元素的约束变得尴尬。
我去了故事板,我基本上在我想要的地方有了 ContainerView 的顶部。然后,我将底部延伸到屏幕底部之外,为 ContainerView 提供足够大的高度……但用户永远不会知道。除了,他们会知道,因为现在 tableView 超出了屏幕,我看不到 tableView 的最后几行。
最终...我不想使用第 3 方库,但我想要一个功能完美的 refreshControl。我该如何解决这个问题?
看来您几乎已经解决了您的问题(通过粗略的解决) 使用您的离屏 UIContainerView 尝试。再试一次,但这次 try:
- 将
numberOfRowsInSection:
中的行数增加 1。
- 在您的
cellForRowAtIndexPath:
方法中,将最后一个单元格的 rowHeight
属性 设置为容器视图在屏幕下方的距离。
第 2 步 如果您使用 tableView:heightForRowAtIndexPath:
方法将不起作用 - 相反,您需要使用其索引设置最后一个单元格的高度。使用此可选方法可能会导致严重的性能问题,并可能导致刷新控件滞后。
1.I已创建下一个架构
2.Added 一些约束
3.In TableViewController
我添加了下一个代码
import UIKit
class TableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.refreshControl = UIRefreshControl(frame: CGRectZero)
self.refreshControl!.addTarget(self, action: "refresh:", forControlEvents: .ValueChanged)
}
func refresh(sender:UIRefreshControl)
{
self.refreshControl?.endRefreshing()
}
}
- 并将示例上传到 github
重要说明 我用过 Xcode 7 和 Swift 2。
我完全无意中重现了您的问题并设法解决了它,但代价是完全没有利润。
如果您对容器视图使用基于边距的约束或任何类型的边距,则似乎会发生跳跃。如果删除约束的边距相关部分,跳跃就会消失。
很奇怪,但似乎是问题所在。只要我为容器添加任何边距相对约束,问题 returns。移除它,显示恢复平滑滚动。
这似乎是一个错误,我认为您需要向 Apple 提交错误报告。
更新:
再看一遍,问题似乎在容器视图不是屏幕的全宽时就出现了。向容器视图添加任何类型的边距(通过相对于边距的布局或通过在约束上设置非零偏移)会导致跳跃行为。
更新:
如果 UITableView 在具有任何边距的容器视图内滚动,似乎会从根本上破坏某些东西。如果您覆盖滚动委托,则滚动视图的内容 offset/bounds 在刷新即将触发时正在更改。这是一些显示问题的调试
Start pulling down:
Scroll bounds = {{0, -127.33333333333333}, {374, 423}}
Scroll pos = [0.000000,-127.333333]
Scroll bounds = {{0, -127.66666666666667}, {374, 423}}
Scroll pos = [0.000000,-127.666667]
Scroll bounds = {{0, -128.33333333333334}, {374, 423}}
Scroll pos = [0.000000,-128.333333]
Ok before here ------->
Activity spinner becomes fully populated. Jump in scroll position upwards.
Scroll bounds = {{0, -104}, {374, 423}}
Scroll pos = [0.000000,-104.000000]
Scroll position corrects itself
Scroll bounds = {{0, -128.33333333333334}, {374, 423}}
Scroll pos = [0.000000,-128.333333]
Scroll position jumps the other direction by the same amount
Scroll bounds = {{0, -151.33333333333334}, {374, 423}}
Scroll pos = [0.000000,-151.333333]
Value changed target action fires. Bounds seem to reset (think 44 is height of refresh control
Scroll bounds = {{0, -44}, {374, 423}}
Scroll pos = [0.000000,-44.000000]
Corrects back
Scroll bounds = {{0, -151.33333333333334}, {374, 423}}
Scroll pos = [0.000000,-151.333333]
Fully corrects to the right scroll position by jumping back.
Ok after here ------>
Scroll bounds = {{0, -128.66666666666666}, {374, 423}}
Scroll pos = [0.000000,-128.666667]
Scroll bounds = {{0, -129}, {374, 423}}
Scroll pos = [0.000000,-129.000000]
Scroll bounds = {{0, -129.33333333333334}, {374, 423}}
Scroll pos = [0.000000,-129.333333]
Scroll bounds = {{0, -129.66666666666666}, {374, 423}}
Scroll pos = [0.000000,-129.666667]
Scroll bounds = {{0, -130}, {374, 423}}
结论
我似乎找不到解决此问题的简便方法。我尝试创建自己的 table 视图控制器,但跳跃消失了,但取而代之的是另一种效果:当您向下滚动时,顶部单元格消失,然后重新出现。我想它与同一个内部问题有关,只是表达方式不同。
不幸的是,您可能不得不忍受这种影响,或者不惜一切代价。我会向 Apple 提交错误报告。
唯一的选择是在 UITableViewCells 中创建边距。您可以使单元格内容视图具有清晰的背景,并使用单元格内容的内部容器视图为单元格引入左右边距。我认为这可能是你最好的机会。
最后...
为了不被打败,您可以对 table 视图的导航控制器应用缩放变换以创建边距,在您的 table 视图控制器中执行以下操作:
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
// Add a scaling transform to the whole embedded controller view.
self.navigationController!.view.transform=CGAffineTransformMakeScale(0.9, 0.9);
}
这使得嵌入式控制器的视图看起来小了 90%,因此它在边框周围有一个边距。将比例更改为以更改边框大小。
不理想,但完美无缺,没有跳转滚动,而且有边框。随着整个内容的缩放,您还可以完全自由地使用圆角等。
跟进我的评论:
要让 UIRefreshControl
与 UICollectionView
或 UITableView
我尝试了很多东西,但最后 UIRefreshControl
真的只在 UITableViewController
.
还有一个问题是调整 UIRefreshControl:
的 tintColor 有时它会为微调器着色,有时不会,有时 tintColor 需要出于某种原因设置在动画块中才能生效。
所以我放弃了UIRefreshControl
,实现了自己的解决方案。它不像在UITableViewController
上设置UIRefreshControl
那么简单,而是:
它工作得很好(或者至少我没能找到未发现的边缘情况:如果你找到它们,请提交一个 pull-request)
您可以实现任何类型的加载视图(旋转的东西,弹跳的东西,甚至可能是地图视图,或者一些 UIKit Dynamics
).
您可以在这里找到它:
我发现在 tableView
上设置 estimatedRowHeight
以匹配 rowHeight
即可解决问题。作为参考,我的设置是 UITableViewController
包含在 UIViewController
中,固定 rowHeight
为 140。
我遇到一个问题,原因是当 UITableViewController 的框架低于特定高度时,UITableViewController refreshControl 会出现故障。
就目前而言,我有一个 UIViewController,在其中我有一个嵌入了 UITableViewController 的 ContainerView。我希望高度为屏幕的 50%。
当我使用 refreshControl 时,出现这种行为:The tableView jumps down at the very end when scrolling down. You'll notice it towards the end of this video when I decide to scroll down slowly.
当ContainerView frame 高于某个值时,不会出现此问题。因此,当高度为屏幕的 75% 时,一切正常,refreshControl 也很流畅。当它是 50% 时,就会出现该错误。
我尝试了两种不同的方法:
self.tableView.frame = CGRectMake(0, numOfPixelsToDropTableBy, self.tableView.frame.size.width, self.tableView.frame.size.height)
是我尝试过的一件事。这样做的问题是,如果您想通过 ContainerView 为 tableView 提供圆角,而您的 ContainerView 仍然占用更多 space 的事实,这会使其他元素的约束变得尴尬。我去了故事板,我基本上在我想要的地方有了 ContainerView 的顶部。然后,我将底部延伸到屏幕底部之外,为 ContainerView 提供足够大的高度……但用户永远不会知道。除了,他们会知道,因为现在 tableView 超出了屏幕,我看不到 tableView 的最后几行。
最终...我不想使用第 3 方库,但我想要一个功能完美的 refreshControl。我该如何解决这个问题?
看来您几乎已经解决了您的问题(通过粗略的解决) 使用您的离屏 UIContainerView 尝试。再试一次,但这次 try:
- 将
numberOfRowsInSection:
中的行数增加 1。 - 在您的
cellForRowAtIndexPath:
方法中,将最后一个单元格的rowHeight
属性 设置为容器视图在屏幕下方的距离。
第 2 步 如果您使用 tableView:heightForRowAtIndexPath:
方法将不起作用 - 相反,您需要使用其索引设置最后一个单元格的高度。使用此可选方法可能会导致严重的性能问题,并可能导致刷新控件滞后。
1.I已创建下一个架构
2.Added 一些约束
3.In TableViewController
我添加了下一个代码
import UIKit
class TableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.refreshControl = UIRefreshControl(frame: CGRectZero)
self.refreshControl!.addTarget(self, action: "refresh:", forControlEvents: .ValueChanged)
}
func refresh(sender:UIRefreshControl)
{
self.refreshControl?.endRefreshing()
}
}
- 并将示例上传到 github
重要说明 我用过 Xcode 7 和 Swift 2。
我完全无意中重现了您的问题并设法解决了它,但代价是完全没有利润。
如果您对容器视图使用基于边距的约束或任何类型的边距,则似乎会发生跳跃。如果删除约束的边距相关部分,跳跃就会消失。
很奇怪,但似乎是问题所在。只要我为容器添加任何边距相对约束,问题 returns。移除它,显示恢复平滑滚动。
这似乎是一个错误,我认为您需要向 Apple 提交错误报告。
更新:
再看一遍,问题似乎在容器视图不是屏幕的全宽时就出现了。向容器视图添加任何类型的边距(通过相对于边距的布局或通过在约束上设置非零偏移)会导致跳跃行为。
更新:
如果 UITableView 在具有任何边距的容器视图内滚动,似乎会从根本上破坏某些东西。如果您覆盖滚动委托,则滚动视图的内容 offset/bounds 在刷新即将触发时正在更改。这是一些显示问题的调试
Start pulling down:
Scroll bounds = {{0, -127.33333333333333}, {374, 423}}
Scroll pos = [0.000000,-127.333333]
Scroll bounds = {{0, -127.66666666666667}, {374, 423}}
Scroll pos = [0.000000,-127.666667]
Scroll bounds = {{0, -128.33333333333334}, {374, 423}}
Scroll pos = [0.000000,-128.333333]
Ok before here ------->
Activity spinner becomes fully populated. Jump in scroll position upwards.
Scroll bounds = {{0, -104}, {374, 423}}
Scroll pos = [0.000000,-104.000000]
Scroll position corrects itself
Scroll bounds = {{0, -128.33333333333334}, {374, 423}}
Scroll pos = [0.000000,-128.333333]
Scroll position jumps the other direction by the same amount
Scroll bounds = {{0, -151.33333333333334}, {374, 423}}
Scroll pos = [0.000000,-151.333333]
Value changed target action fires. Bounds seem to reset (think 44 is height of refresh control
Scroll bounds = {{0, -44}, {374, 423}}
Scroll pos = [0.000000,-44.000000]
Corrects back
Scroll bounds = {{0, -151.33333333333334}, {374, 423}}
Scroll pos = [0.000000,-151.333333]
Fully corrects to the right scroll position by jumping back.
Ok after here ------>
Scroll bounds = {{0, -128.66666666666666}, {374, 423}}
Scroll pos = [0.000000,-128.666667]
Scroll bounds = {{0, -129}, {374, 423}}
Scroll pos = [0.000000,-129.000000]
Scroll bounds = {{0, -129.33333333333334}, {374, 423}}
Scroll pos = [0.000000,-129.333333]
Scroll bounds = {{0, -129.66666666666666}, {374, 423}}
Scroll pos = [0.000000,-129.666667]
Scroll bounds = {{0, -130}, {374, 423}}
结论
我似乎找不到解决此问题的简便方法。我尝试创建自己的 table 视图控制器,但跳跃消失了,但取而代之的是另一种效果:当您向下滚动时,顶部单元格消失,然后重新出现。我想它与同一个内部问题有关,只是表达方式不同。
不幸的是,您可能不得不忍受这种影响,或者不惜一切代价。我会向 Apple 提交错误报告。
唯一的选择是在 UITableViewCells 中创建边距。您可以使单元格内容视图具有清晰的背景,并使用单元格内容的内部容器视图为单元格引入左右边距。我认为这可能是你最好的机会。
最后...
为了不被打败,您可以对 table 视图的导航控制器应用缩放变换以创建边距,在您的 table 视图控制器中执行以下操作:
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
// Add a scaling transform to the whole embedded controller view.
self.navigationController!.view.transform=CGAffineTransformMakeScale(0.9, 0.9);
}
这使得嵌入式控制器的视图看起来小了 90%,因此它在边框周围有一个边距。将比例更改为以更改边框大小。
不理想,但完美无缺,没有跳转滚动,而且有边框。随着整个内容的缩放,您还可以完全自由地使用圆角等。
跟进我的评论:
要让 UIRefreshControl
与 UICollectionView
或 UITableView
我尝试了很多东西,但最后 UIRefreshControl
真的只在 UITableViewController
.
还有一个问题是调整 UIRefreshControl:
的 tintColor 有时它会为微调器着色,有时不会,有时 tintColor 需要出于某种原因设置在动画块中才能生效。
所以我放弃了UIRefreshControl
,实现了自己的解决方案。它不像在UITableViewController
上设置UIRefreshControl
那么简单,而是:
它工作得很好(或者至少我没能找到未发现的边缘情况:如果你找到它们,请提交一个 pull-request)
您可以实现任何类型的加载视图(旋转的东西,弹跳的东西,甚至可能是地图视图,或者一些
UIKit Dynamics
).
您可以在这里找到它:
我发现在 tableView
上设置 estimatedRowHeight
以匹配 rowHeight
即可解决问题。作为参考,我的设置是 UITableViewController
包含在 UIViewController
中,固定 rowHeight
为 140。