Stuart Breckenridge

Optional vs Empty Table Views in Swift

A recent post on Natasha The Robot looks at different (but equally valid) approaches for handling the display of data when table views are empty or optional.

I prefer a variation on the non-optional approach using the didSet observer.

// Tableview Data Source
var dataArray = [String]() {
        didSet {
            dataTable.reloadData()
        }
    }

didSet is not called during initialisation of the array, so using the observer ensures that the tableView isn’t reloaded until a new value is set.

In viewDidLoad, I hide the tableView until data is available:

override func viewDidLoad() {
        super.viewDidLoad()
    
        // Hide TableView 
        dataTable.alpha = 0.0
        
        // Load TableView
        loadTableViewData()
    }

loadTableViewData parses JSON in the background and passes an array back in the completion handler (which is called on the main thread)1:

private func loadTableViewData()
    {
        // Show indicator while loading.
        UIApplication.sharedApplication().networkActivityIndicatorVisible = true
        
        let parser = JSONParser()
        parser.parseJSON { (list) -> Void in
            // Hide indicator, set dataArray to list, show tableView
            UIApplication.sharedApplication().networkActivityIndicatorVisible = false
            
            self.dataArray = list
            
            UIView.animateWithDuration(0.2, animations: { () -> Void in
                self.dataTable.alpha = 1.0
            })
        }
    }

In the UITableViewDataSource functions, there is no need to consider optionals:

extension ViewController: UITableViewDataSource
{
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataArray.count
    }
    
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("Cell") as UITableViewCell!
        
        cell.textLabel?.text = dataArray[indexPath.row]
        
        return cell
    }
}

I’ve uploaded a sample project to GitHub which contains some sample JSON.

  1. I’m using networkActivityIndicatorVisible as a placeholder to show parse progress. ↩︎


Supported by