如何在没有tableView的情况下拉动刷新?

问题描述

我有一个控制器:

final class CategoryBreakdownViewController: UIViewController {
  
    private let scrollView = UIScrollView(alwaysBounceVertical: true)
    var refreshControl = UIRefreshControl()

我在 viewDidLoad 中的何处尝试在没有 tableView 的情况下实现拉动刷新:

 private func setupRefreshControl() {    
        scrollView.alwaysBounceVertical = true
        scrollView.bounces  = true
        refreshControl.addTarget(self,action: #selector(updateView),for: .valueChanged)
        self.scrollView.addSubview(refreshControl)
    }
    
    @objc func updateView() {
        SyncScheduler.syncImmediately(
            success: {
                self.refreshControl.endRefreshing()
            },failure: { [weak self] errorMessage in
                self?.present(message: errorMessage,style: .error)
                self?.refreshControl.endRefreshing()
            }
        )
    }

但在我的情况下,此解决方案不起作用,如何解决此问题?

解决方法

您的方法似乎没有任何问题。

这是一个完整的例子——它添加了一个“全视图”scrollView,带有一个 200 pt 高的红色子视图(所以我们可以看到效果)。

向下拖动时,您应该会看到 UIRefreshControl“微调器”出现。向下拖得足够远,它将调用 updateView() 函数。由于我们没有您的 SyncScheduler 代码,我添加了一个 2 秒的异步延迟来模拟该过程:

final class CategoryBreakdownViewController: UIViewController {
    
    private let scrollView = UIScrollView()
    var refreshControl = UIRefreshControl()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        scrollView.backgroundColor = .systemTeal
        scrollView.translatesAutoresizingMaskIntoConstraints = false

        let testView = UIView()
        testView.backgroundColor = .red
        testView.translatesAutoresizingMaskIntoConstraints = false

        scrollView.addSubview(testView)
        view.addSubview(scrollView)
    
        let contentGuide = scrollView.contentLayoutGuide
        let frameGuide = scrollView.frameLayoutGuide
        
        NSLayoutConstraint.activate([
            scrollView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),scrollView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),testView.topAnchor.constraint(equalTo: contentGuide.topAnchor,constant: 20.0),testView.leadingAnchor.constraint(equalTo: contentGuide.leadingAnchor,testView.trailingAnchor.constraint(equalTo: contentGuide.trailingAnchor,constant: -20.0),testView.bottomAnchor.constraint(equalTo: contentGuide.bottomAnchor,testView.widthAnchor.constraint(equalTo: frameGuide.widthAnchor,constant: -40.0),testView.heightAnchor.constraint(equalToConstant: 200.0),])

        setupRefreshControl()
    }
    
    private func setupRefreshControl() {
        scrollView.alwaysBounceVertical = true
        scrollView.bounces = true
        refreshControl.addTarget(self,action: #selector(updateView),for: .valueChanged)
        self.scrollView.addSubview(refreshControl)
    }
    
    @objc func updateView() {

        // simulate a background process that takes 2 seconds
        DispatchQueue.main.asyncAfter(deadline: .now() + 2.0,execute: {
            self.refreshControl.endRefreshing()
        })
        
//      SyncScheduler.syncImmediately(
//          success: {
//              self.refreshControl.endRefreshing()
//          },//          failure: { [weak self] errorMessage in
//              self?.present(message: errorMessage,style: .error)
//              self?.refreshControl.endRefreshing()
//          }
//      )
        
    }
}
,

所以你缺少两行代码:

self.scrollView.scrollEnabled = true
self.scrollView.alwaysBounceVertical = true

var alwaysBounceVertical: Bool // 默认没有。如果是 YES 并且反弹是 YES,即使内容小于边界,也允许垂直拖动。

请试试这个。谢谢