AboutContact

UIRefreshControl: how to use the iOS UITableView pull to refresh in swift 2

In this new swift tutorial you'll see how to implement the pull to refresh iOS functionality for a UITableView using the UIRefreshControl component. In this tutorial you'll see how to download data from an external url using the NSUrlSession swift utility, how to define and fill the UITableView, and how to add inside the UITableView the UIRefreshControl, to add the pull to refresh funcionality.

In this pull to refresh example we'll define a simple UITableView that will fill the data downloaded from a server. The data in this example are just Int numbers. When the table is pulled down, the refresh is called, and new data are requested by sending with a post the last received number. In this way at every refresh just the newest data are sent from the server.

swift: pull to refresh example

Configure the project

Let's create a new iOS single view app. We need to allow the http protocol in swift 2. You'll need to edit the info.plist file. Search for the info.plist file, right click on it, choose open as - source code and write the following lines:

<key>NSAppTransportSecurity</key>

<dict>

	<key>NSAllowsArbitraryLoads</key>

	<true/>

</dict>

Layout definition

 

Open the main.storyboard and disable the use size classes features. Let's now add inside the UIViewController an UITablewView iOS component and inside it add a UITableViewCell component. Add also the top, bottom, left, right constraints for the UITablewViewCell to anchor it to the view margins.

swift: pull to refresh

Open the Attribute Inspector for the UITablewViewCell and write cell as an identifier.

Using the Assistant Editor link also the UITableView to a variable, in this tutorial I'll call it table.

Define the required variables

Let's now define the variables that are required by this project.

    var refreshControl = UIRefreshControl()
    var dateFormatter = NSDateFormatter()

    let url_to_request = "https://www.kaleidosblog.com/tutorial/pulltorefresh.php"
    var last_index = 0
    
    var list:[Int] = [Int]()

The refreshControl variable (type: UIRefreshControl) is the core for the pull to refresh functionality. The UIRefreshControl functionality is natively implemented in Swift, since iOS 6. The dateFormatter is used to write inside the refreshControl the last updated time. The last_index is used to define the last received index, while the list array is the list of integer that will be used to store the received data.

Download the data from url using NSURLSession

Let's now define the function that will download the data from an url in an asynchronous way using the NSURLSession swift function. The function will send a post parameter to let the server know the latest received data, and send in this way only the newest. As soon as the data is received, the json extraction process is performed. The data is added at the top of the array using the insert function. The table is then refreshed with the new data on the main thread, and the refreshControl is hidden and updated.

  func data_request()
    {
        let url:NSURL = NSURL(string: url_to_request)!
        let session = NSURLSession.sharedSession()
        
        let request = NSMutableURLRequest(URL: url)
        request.HTTPMethod = "POST"
        request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringCacheData
        
        let paramString = "last_index=" + last_index.description
        request.HTTPBody = paramString.dataUsingEncoding(NSUTF8StringEncoding)
        
        let task = session.dataTaskWithRequest(request) {
            (
            let data, let response, let error) in
            
            guard let _:NSData = data, let _:NSURLResponse = response  where error == nil else {
                print("error")
                return
            }

            
            self.extract_data(data!)
        }
        
        task.resume()
        
    }
    
    
    func extract_data(data:NSData)
    {
        var json: AnyObject?

        
        do
        {
            json = try NSJSONSerialization.JSONObjectWithData(data, options: [])
        }
        catch
        {
            return
        }
        
        guard let data_array = json as? NSArray else
        {
            return
        }
        
        
        for(var i = 0; i < data_array.count; i++)
        {
            if let add = data_array[i] as? Int
            {
                list.insert(add, atIndex: 0)
                last_index = add
            }
        }
        
        
        dispatch_async(dispatch_get_main_queue(), {
            self.table.reloadData()
            
            let now = NSDate()
            
            let updateString = "Last Updated at " + self.dateFormatter.stringFromDate(now)
           
            self.refreshControl.attributedTitle = NSAttributedString(string: updateString)
            
            
            if self.refreshControl.refreshing
            {
                self.refreshControl.endRefreshing()
            }

            
            return
        })
        
        
    }
    
    

Initialize the UIRefreshControl

Let's now define the UIRefreshControl functionality and the table view delegates method. The UIRefreshControl istance will be added inside the tableview view. Be sure to add at the top, after the UIViewController method, also the UITableViewDataSource and UITableViewDelegate. In this way you'll say to swift that the current class will implement the delegates methods for the UITableView.

   override func viewDidLoad() {
        super.viewDidLoad()

        
        self.dateFormatter.dateStyle = NSDateFormatterStyle.ShortStyle
        self.dateFormatter.timeStyle = NSDateFormatterStyle.LongStyle
        
        refreshControl.backgroundColor = UIColor.clearColor()
        refreshControl.tintColor = UIColor.blackColor()
        refreshControl.attributedTitle = NSAttributedString(string: "Pull to refresh")
        
        refreshControl.addTarget(self, action: "PullRefresh", forControlEvents: UIControlEvents.ValueChanged)
        
        self.table.addSubview(refreshControl)
     
 
        table.dataSource = self
        table.delegate = self
        
        
        data_request()
    }

    internal func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
        return list.count
    }
    
    
    internal func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
    {
         let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as UITableViewCell
        
         cell.textLabel?.text = list[indexPath.row].description
        
        return cell
    }

Here you'll find the project for this example: download.

 

 

Leave a comment












AboutContactPrivacy