当UITableViewController frame.height很小时,UITableViewController refreshControl很麻烦

时间:2015-09-15 21:27:05

标签: ios swift uitableview uicontainerview uirefreshcontrol

我遇到的问题是,当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框架高于某个值时,不会发生此问题。因此,当高度为屏幕的75%时,一切都运行良好,refreshControl也很流畅。当它是50%时,就会发生这个错误。

我尝试了两件不同的事情:

  1. self.tableView.frame = CGRectMake(0, numOfPixelsToDropTableBy, self.tableView.frame.size.width, self.tableView.frame.size.height)是我尝试过的一件事。这样做的问题是,如果你想通过ContainerView给tableView圆角以及你的ContainerView仍占用更多空间这一事实,这会使其他元素的约束变得尴尬。

  2. 我去了故事板,我基本上拥有了我想要的ContainerView的顶部。然后,我将底部延伸到屏幕底部以外,为ContainerView提供足够大的高度......但用户永远不会知道。除此之外,他们会知道,因为现在tableView超出了屏幕,我无法看到tableView的最后几行。

  3. 最终......我不想使用第三方库,但我想要一个功能完善的refreshControl。我该如何解决这个问题?

5 个答案:

答案 0 :(得分:5)

1.我已经创建了下一个架构 enter image description here
2.增加了一些限制因素 enter image description here
3.在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()
    }
}
  1. 并将示例上传到github
  2. 重要提示我使用过Xcode 7和Swift 2.

答案 1 :(得分:1)

我设法完全意外地重新创建了您的问题,并设法修复它,但代价是没有任何边距。

如果您对容器视图使用基于边距的约束或任何类型的边距,则似乎会发生跳跃。如果删除约束的边距相对部分,则跳跃消失。

很奇怪,但似乎是个问题。只要我为容器添加任何边距相对约束,问题就会返回。删除它,显示屏返回平滑滚动。

这似乎是一个错误,我认为你需要向Apple提出错误报告。

<强>更新

再看一下,只要容器视图不是屏幕的整个宽度,问题就会出现。向容器视图添加任何类型的边距(通过相对于边距的布局或通过在约束上设置非零偏移)会导致跳跃行为。

<强>更新

UITableView在具有任何边距的容器视图内滚动似乎会从根本上破坏某些东西。如果覆盖滚动委托,则在刷新即将触发时正在更改滚动视图的内容偏移/边界。这是一些显示问题的调试

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}}

<强>结论

似乎没有简单的方法可以解决这个问题。我尝试创建自己的表视图控制器,跳跃消失但被另一种效果取代:当你向下滚动顶部单元格消失时,然后重新出现。我想它与同一个内部问题有关,只是表达不同。

Unfortunatley看起来你可能不得不忍受这种效果或者没有利润。我会向Apple提出错误报告。

只有替代选项才能在UITableViewCells中创建边距。您可以使单元格内容视图具有清晰的背景,并使用内容容器视图为您的单元格引入左右边距。我想这可能是你最好的机会。

最后......

不要失败,您可以将缩放变换应用于表视图的导航控制器,以在表视图控制器中创建执行以下操作的边距:

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%,因此它在边框周围有一个边距。将比例更改为更改边框大小。

不理想,但没有跳转滚动并且有边框,效果很好。它还可以让你完全自由地使用圆角等,因为整个内容都是缩放的。

答案 2 :(得分:0)

您似乎已经使用屏幕外UIContainerView尝试几乎解决了您的问题(使用粗略的工作)。再试一次,但这次尝试

  1. numberOfRowsInSection:内的行数增加 1
  2. cellForRowAtIndexPath:方法中,将最后一个单元格的rowHeight属性设置为容器视图在屏幕下方的距离。
  3. 第2步 如果您正在使用tableView:heightForRowAtIndexPath:方法,那么您将无法工作 - 相反,您将会这样做需要使用其索引设置最后一个单元格的高度。使用此可选方法可能会导致严重的性能问题,并且还可能导致滞后的刷新控件。

答案 3 :(得分:0)

跟进我的评论:

要使 UIRefreshControl 能够与 UICollectionView UITableView 进行良好协作,我可以#&# 39;我尝试了很多东西,但最终 UIRefreshControl UITableViewController 中才能正常运作。

然后还有调整 UIRefreshControl: 的tintColor的问题,有时它会为微调器着色,有时它不会,有时tintColor需要设置在由于某种原因生效的动画块生效。

所以我放弃了 UIRefreshControl ,并实施了我自己的解决方案。这不像在 UIRefreshControl 上设置UITableViewController那么简单,但是:

  • 它完美运作(或者至少我找不到未发现的边缘情况:如果你找到它们,请提出拉动请求)

  • 你可以实现任何类型的加载视图(旋转的东西,弹跳的东西,甚至是地图视图,或某些 UIKit Dynamics )。

    < / LI>

你可以在这里找到它:

JRTRefreshControl

答案 4 :(得分:0)

我发现一些案例,只需在estimatedRowHeight上设置tableView来匹配rowHeight即可解决故障。作为参考,我的设置是一个UITableViewController内的UIViewController,其中rowHeight固定为140。