iOS Swift UITableView pull to refresh example

iOS Swift UITableView pull to refresh example

The way to do this is ti take help of UIRefreshControl class, which provides a standard control that you attach to any UIScrollView object, including table views and collection views. Add this control to scrollable views to give your users a standard way to refresh their contents. When the user drags the top of the scrollable content area downward, the scroll view reveals the refresh control, begins animating its progress indicator, and notifies your app. You use that notification to update your content and dismiss the refresh control.

        // Add Refresh Control to Table View
        if #available(iOS 10.0, *) {
            myTableView.refreshControl = refreshControl
        } else {
            myTableView.addSubview(refreshControl)
        }
        
        //add method to refresh data
        refreshControl.addTarget(self, action: #selector(self.refreshTable), for: .valueChanged)

Complete Source for UIViewController using UIRefreshControl


import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
    private var myTableView: UITableView!
    private var tableData: [String]!
    private let refreshControl = UIRefreshControl()
    
    override func viewDidLoad() {
        
        super.viewDidLoad()
        self.navigationItem.title = "Main View"
        
        //get my sample data for loading the table view
        tableData = getRandomData()
        
        //setup my table view
        myTableView = UITableView()
        myTableView.register(UITableViewCell.self, forCellReuseIdentifier: "MyCell")
        myTableView.dataSource = self
        myTableView.delegate = self
        myTableView.translatesAutoresizingMaskIntoConstraints = false
        myTableView.tableFooterView = UIView()
        self.view.addSubview(myTableView)
        
        //auto layout for the table view
        let views = ["view": view!, "tableView" : myTableView]
        var allConstraints: [NSLayoutConstraint] = []
        allConstraints += NSLayoutConstraint.constraints(withVisualFormat: "V:|[tableView]|", options: [], metrics: nil, views: views as [String : Any])
        allConstraints += NSLayoutConstraint.constraints(withVisualFormat: "H:|[tableView]|", options: [], metrics: nil, views: views as [String : Any])
        NSLayoutConstraint.activate(allConstraints)
        
        // Add Refresh Control to Table View
        if #available(iOS 10.0, *) {
            myTableView.refreshControl = refreshControl
        } else {
            myTableView.addSubview(refreshControl)
        }
        
        //add method to refresh data
        refreshControl.addTarget(self, action: #selector(self.refreshTable), for: .valueChanged)
        
        //Setting the tint Color of the Activity Animation
        refreshControl.tintColor = UIColor.red
        
        //Setting the attributed String to the text
        let refreshString = NSMutableAttributedString(string: "Please wait loading...")
        refreshString.addAttribute(.foregroundColor, value: UIColor.red,
                                   range: NSRange(location: 0, length: 6))
        refreshString.addAttribute(.foregroundColor, value: UIColor.green,
                                   range: NSRange(location: 7, length: 4))
        refreshString.addAttribute(.foregroundColor, value: UIColor.blue,
                                   range: NSRange(location: 12, length: 10))
        refreshControl.attributedTitle = refreshString
        
    }
    
    @objc func refreshTable(toRefresh sender: UIRefreshControl?) {
        
        //do work off the main thread
        DispatchQueue.global(qos: .default).async(execute: {
        
            // Simulate network traffic (sleep for 2 seconds)
            Thread.sleep(forTimeInterval: 2)
            
            //Update data
            self.tableData = self.getRandomData()
            
            //Call complete on the main thread
            DispatchQueue.main.sync(execute: {
                print("all done here...")
                sender?.endRefreshing()
                self.myTableView.reloadData()
            })
        })
    }

    
    //when user taps on the row
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("Selected: \(tableData[indexPath.row])")
    }
    
    //no of sections for the table view
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    
    //number of rows for that section
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return tableData.count
    }
    
    //render the cell and display data
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath) 
        
        let myData = tableData[indexPath.row]
        cell.textLabel!.text = myData
        return cell
    }
    
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        
    }
    
    //get data for display
    func getRandomData() -> [String] {
        
        var myData: [String] = []
        let random = Int.random(in: 1..<10)
        for i in 1...random {
            myData.append("This is my row# \(i)")
        }
        
        return myData
        
    }
    
}

No comments:

Post a Comment

NO JUNK, Please try to keep this clean and related to the topic at hand.
Comments are for users to ask questions, collaborate or improve on existing.