UIScrollView中的UIRefreshControl不会在endRefreshing时消失

时间:2019-05-23 14:50:12

标签: ios swift cocoa-touch uiscrollview uirefreshcontrol

我试图在UIScrollView中使用UIRefreshControll,但是我有一个问题,我需要滚动很多次才能刷新它。我需要用双手使它工作,所以我决定编写一些滚动逻辑来开始刷新。

现在的问题是,有时endRefreshing函数不会使UIRefreshControll视图消失,而我最终将其永久保留在那里。

我尝试在主队列中延迟调用endRefreshing,但它不起作用。我也尝试过将isHidden设置为true,还可以将removeFromSuperView设置为true。我没有运气能使它工作。

import UIKit

class RefreshableView : UIView {

    @IBOutlet weak var scrollView: UIScrollView!

    private let refreshControl = UIRefreshControl()
    private var canRefresh = true
    var refreshFunction: (() -> ())?

    func setupUI() {
        backgroundColor = ColorName.grayColor.color
        scrollView.refreshControl = refreshControl
    }

    func endRefreshing() {
        self.refreshControl.endRefreshing()
    }
}

extension RefreshableView: UIScrollViewDelegate {

    func scrollViewDidScroll(_ scrollView: UIScrollView) {

        if scrollView.contentOffset.y < -100 {
            if canRefresh && !self.refreshControl.isRefreshing {

                self.canRefresh = false
                self.refreshControl.beginRefreshing()

                self.refreshFunction?()
            }
        } else if scrollView.contentOffset.y >= 0 {
            self.canRefresh = true
        }
    }
}

1 个答案:

答案 0 :(得分:1)

滚动视图的refreshControl自动处理“套用刷新”功能,因此您不需要任何scrollViewDidScroll()代码。

假设您的故事板看起来像这样,其中:

  • 红色背景的视图是RefreshableView类的实例
  • 它包含一个滚动视图(通过@IBOutlet连接)
  • 以及滚动视图中的一些内容(这里我只有一个标签)

enter image description here

您的代码可以像这样:

class RefreshableView : UIView {

    @IBOutlet var scrollView: UIScrollView!

    private let refreshControl = UIRefreshControl()

    var refreshFunction: (() -> ())?

    func setupUI() {
        backgroundColor = .gray

        refreshControl.addTarget(self, action: #selector(didPullToRefresh), for: .valueChanged)

        scrollView.refreshControl = refreshControl
    }

    @objc func didPullToRefresh() {
        print("calling refreshFunction in controller")
        self.refreshFunction?()
    }

    func endRefreshing() {
        print("end refreshing called from controller")
        self.refreshControl.endRefreshing()
    }

}

class RefreshTestViewController: UIViewController {

    @IBOutlet var theRefreshableView: RefreshableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        theRefreshableView.setupUI()

        theRefreshableView.refreshFunction = {
            print("simulating refresh for 2 seconds...")
            DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
                [weak self] in
                guard let self = self else { return }
                // do what you want to update the contents of theRefreshableView
                // ...
                // then tell theRefreshableView to endRefreshing
                self.theRefreshableView.endRefreshing()
            }
        }
    }

}