iOS UITableView偏移刷新控件

时间:2018-08-31 22:36:28

标签: ios swift uitableview uirefreshcontrol

我有一个UITableView受限于超级视图。因此,第一个单元格是超级视图的顶部。这意味着在iPhone X上,第一个单元会在缺口下方渗出,并进入状态栏区域。完全正确。我想要该单元格在槽口下流血并进入状态栏区域,这是当前结果。

问题是,我还希望对该表视图进行刷新控制,以便用户可以拉动以刷新内容。但是,当您在iPhone X上拉动刷新时,刷新控件会被切口切断。我不希望刷新控件被槽口切断。

所以基本上我想做的是将表视图限制为超级视图,但将刷新控件限制为安全区域。

我已经看过了,看起来苹果没有提供许多属性或方法来自定义刷新控件的行为。

我已经考虑过使用某种类型的自定义解决方案,但是我想到的每个自定义解决方案都失去了刷新控件和表视图滚动等所有预构建的物理特性。幕后逻辑如此之多,我真的不想牺牲刷新的感觉,以及对用户的感觉,因为这已成为iOS中的常见操作。

关于如何使第一个单元格在槽口下出血(限制为超级视图)但确保刷新控制不会被槽口(限于安全区域)切断的任何想法?

我还在下面附上了屏幕截图,其中显示了单元格如何渗入状态栏,以及缺口如何切断刷新控件。

编辑:我还向GitHub here发布了一个示例项目。

但是与刷新控件相关的基本代码如下。

private lazy var refreshControl = UIRefreshControl()
override func viewDidLoad() {
    super.viewDidLoad()

    refreshControl.addTarget(self, action: #selector(handleRefresh), for: .valueChanged)
    tableView.refreshControl = refreshControl
}

@objc func handleRefresh() {
    DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
        self.refreshControl.endRefreshing()
    }
}

enter image description here

enter image description here

3 个答案:

答案 0 :(得分:11)

您可以受益于UIScrollView的基础。在您的github示例中,您已获得了所需的一切,因此,如果使用以下方法扩展它:

extension ViewController: UIScrollViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        if scrollView.contentOffset.y < 0 {
            topConstraint.constant = -scrollView.contentOffset.y/2
        } else {
            topConstraint.constant = 0
        }
    }
}

每次contentOffset开始低于0并使您的tableView移至底部时,无论什么反应,只要关闭或向下滚动它就会被设置为默认值- 0

这样,您将获得与拖动力/距离有关的平滑动画,如下所示:

enter image description here

答案 1 :(得分:5)

该解决方案很简单,您可以在viewDidLoad中设置刷新控件的边界。使用所需的y偏移值(例如50)

  refreshControl.addTarget(self, action: #selector(handleRefresh), for: .valueChanged)
  refreshControl.bounds = CGRect(x: refreshControl.bounds.origin.x,
                                 y: 50,
                                 width: refreshControl.bounds.size.width,
                                 height: refreshControl.bounds.size.height)
  tableView.refreshControl = refreshControl

And now it looks like this

更新:

您可以在刷新开始时添加内容插图,然后在结束时重新显示。

  override func viewDidLoad() {
        super.viewDidLoad()


      refreshControl.addTarget(self, action: #selector(handleRefresh), for: .valueChanged)
      refreshControl.bounds = CGRect(x: refreshControl.bounds.origin.x,
                                     y: -100,
                                     width: refreshControl.bounds.size.width,
                                     height: refreshControl.bounds.size.height);
      tableView.refreshControl = refreshControl
    }

    @objc func handleRefresh() {
      self.tableView.contentInset = UIEdgeInsets(top: 200, left: 0, bottom: 0, right: 0)
        DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
          self.refreshControl.endRefreshing()
          self.tableView.contentInset = UIEdgeInsets.zero
          self.tableView.setContentOffset(.zero, animated: true)
        }
    }

答案 2 :(得分:-2)

表格视图的顶部约束必须相对于上边距

enter image description here

enter image description here