Search code examples
iosswiftuitableviewreloaddatapull-to-refresh

table view.reloadData() doesn't work within the table view


table view.reloadData() updates the table view after I change view controller and I come back. I add a pull to refresh functionality :

    lazy var refreshControl: UIRefreshControl = {
    let refreshControl = UIRefreshControl()
    refreshControl.addTarget(self, action: "handleRefresh:", forControlEvents: UIControlEvents.ValueChanged)
    refreshControl.backgroundColor = UIColor.purpleColor()
//        dispatch_async(dispatch_get_main_queue(), { () -> Void in
//            self.tableView.reloadData()
//        })
    return refreshControl
    }()

this is outside any methods. Then in the viewdidload():

    override func viewDidLoad() {
        self.tableView.addSubview(self.refreshControl)
 }

The handleRefresh function is this:

    func handleRefresh(refreshControl: UIRefreshControl) {
    // Do some reloading of data and update the table view's data source
    // Fetch more objects from a web service, for example...
    fetch()    // Fetches new data

    refreshControl.endRefreshing()
    self.tableView.reloadData()
}

This works,but only after I exit the view controller and come back. I think the problem is that the array that use to populate the tableview cells is a global array, meaning that it is declared in the same scope as the import statements, but I'm not sure. I would like some advice on how to make the pull to refresh "refresh" the table view as soon as it is pulled.

This is my fetch code:

func fetch(){
    var query = PFQuery(className:"Photo")
    query.whereKey("friend", equalTo:"bob")
    query.findObjectsInBackgroundWithBlock {
        (objects: [AnyObject]?, error: NSError?) -> Void in
        if error == nil {
            // The find succeeded.
            self.getImageData(objects as [PFObject])
            if let objects = objects as? [PFObject] {
                PhotoInfoArray = objects  // This is the global array that stores photo information, date created, etc.
            }
        } else {
            println("Error: \(error!) \(error!.userInfo!)")
        }
    }
}

func getImageData(objects: [PFObject]) {
    for object in objects {

        let thumbNail = object["Image"] as PFFile


        thumbNail.getDataInBackgroundWithBlock({
            (imageData: NSData!, error: NSError!) -> Void in
            if (error == nil) {
                let image = UIImage(data:imageData)
                //image object implementation
                imageArray.append(image!)// this is the global array that stores the actual pictures
                //                    println(image)
            }

        })//getDataInBackgroundWithBlock - end
    }//for - end
}

These functions use Parse as a backend.


Solution

  • I think it might be a good idea to keep track of what is actually in your array because I have never seen a scenario where self.tableView.reloadData() doesn't work.
    I'd advise to print the array in viewWillAppear or viewDidAppear.

    Maybe it might be handy to add a success call then if you need to wait for some other process to finish like so:

        func someFunction(success: ((success: Bool) -> Void))) {
            //Perform some tasks here
            success(success: true)
        }
    

    And then in the viewcontroller expecting the results it would look like this:

        someFunction({ (bool) -> Void in 
           if bool {
              self.tableView.reloadData()
           }
        })