简体   繁体   中英

How to pull to refresh without tableView?

I have next controller:

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

Where in viewDidLoad I'm trying to implement pull to refresh without 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()
            }
        )
    }

But in my case this solution doesn't worked, how to solve this problem?

There doesn't appear to be anything wrong with your approach.

Here is a complete example -- it adds a "full view" scrollView, with a 200-pt tall red subview (so we can see the effect).

When you drag down, you should see the UIRefreshControl "spinner" appear. Drag down far enough, and it will call the updateView() func. Since we don't have your SyncScheduler code, I added a 2-second async delay to simulate the process:

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, constant: 20.0),
            testView.trailingAnchor.constraint(equalTo: contentGuide.trailingAnchor, constant: -20.0),
            testView.bottomAnchor.constraint(equalTo: contentGuide.bottomAnchor, constant: -20.0),

            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()
//          }
//      )
        
    }
}

So you are missing two line of code:

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

var alwaysBounceVertical: Bool // default NO. if YES and bounces is YES, even if content is smaller than bounds, allow drag vertically.

Please try this. Thanks

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM