简体   繁体   中英

the table view is not being updated after download the data

First of all, to avoid my bad English, I uploaded a video showing my problem

http://www.mediafire.com/download/j6krsa274o80ik9/Screen_Recording.mov

Second, I have a UITableViewController, that uses a remote API to download data. the data contains many image URLs, my first problem is that the tableView is not being updated even though i am doing .reloadData() function

my second problem is that in the function:

tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

I download the images, which I had got their urls from the first call, then eventhing works good but I can't see the image unless I clicked on the row

Please see the video, it is easier to understand

Here is my code: (I gave you the full code of my UITableView because, it is simple, and because it has two functions, and they are the ones that making me problems)

class Physicst: NSObject {
    let image : String
    var imageData: UIImage?
    let name : NSString
    init(image: String, name: NSString) {
        self.image = image
        self.name = name
    }
}

class PhysicistTableViewController: UITableViewController {

    var physicsts : [Physicst]?

    @IBOutlet var physicstsTableView: UITableView!



    override func viewDidLoad() {
        super.viewDidLoad()
        loadDataFromDBPedia()
    }

    func loadDataFromDBPedia()  {
        let session = NSURLSession.sharedSession()
        var url = "http://dbpedia.org/sparql/"
        let query = "http://dbpedia.org&query=select * {?o  dbo:thumbnail ?p . ?o dbo:award dbr:Nobel_Prize_in_Physics} limit 10"
        url = url + "?default-graph-uri=" + query.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())!
        url = url + "&format=JSON&CXML_redir_for_subjs=121&CXML_redir_for_hrefs=&timeout=30000&debug=on"
        let request = NSMutableURLRequest(URL: NSURL(string: url)!)
        let task = session.dataTaskWithRequest(request, completionHandler: {(data, response ,error) in
            if let error = error {
                print ("\(error)")
            }
            if let response = response {
                let httpResponse = response as! NSHTTPURLResponse
                let statusCode = httpResponse.statusCode
                print("Status code = \(statusCode)")
            }
            if let data = data  {
                do {
                    let jsonResponse = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions())
                    let binding = jsonResponse["results"]!!["bindings"] as! NSArray
                    for oneBinding in binding {
                        let name = oneBinding["o"]!!["value"] as! NSString
                        var image = oneBinding["p"]!!["value"] as! String
                        image = image.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!
                        let physicst = Physicst(image: image, name: name)
                        if self.physicsts == nil {
                            self.physicsts = [Physicst]()
                        }
                        self.physicsts!.append(physicst)
                    }
                    self.physicstsTableView.reloadData()
                }catch _ {
                    print ("not well json-formatted response")
                }
            }
        })
        task.resume()
    }

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if self.physicsts == nil {
            return 0
        }else {
            return self.physicsts!.count
        }
    }


    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("physicstCell")! as UITableViewCell
        let row = indexPath.row
        let physicst = self.physicsts![row]
        cell.textLabel?.text = physicst.name as String
        if (physicst.imageData == nil) {
            let session = NSURLSession.sharedSession()
            let url = NSURL(string: physicst.image as String)
            if let url = url {
                let request = NSMutableURLRequest(URL: url)
                let task = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
                    if let data = data {
                        let imageData = UIImage(data: data)
                        cell.imageView?.image = imageData
                        physicst.imageData = imageData
                        self.physicstsTableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.None)
                    }
                })
                task.resume()
            }else {
                print ("nill URL \(physicst.image)")
            }
        }else {
            cell.imageView?.image = physicst.imageData!
        }
        return cell
    }
}

**fell free to copy/paste it, there is no custom cell, so it should work **

tableView reload should be called on main thread. session.dataTaskWithRequest completion block is called on background thread performing UI Operations on background thread might lead to serious consequences. I believe the problem you are facing is just one of those consequences. Modify the code as follow.

func loadDataFromDBPedia()  {
            let session = NSURLSession.sharedSession()
            var url = "http://dbpedia.org/sparql/"
            let query = "http://dbpedia.org&query=select * {?o  dbo:thumbnail ?p . ?o dbo:award dbr:Nobel_Prize_in_Physics} limit 10"
            url = url + "?default-graph-uri=" + query.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())!
            url = url + "&format=JSON&CXML_redir_for_subjs=121&CXML_redir_for_hrefs=&timeout=30000&debug=on"
            let request = NSMutableURLRequest(URL: NSURL(string: url)!)
            let task = session.dataTaskWithRequest(request, completionHandler: {(data, response ,error) in
                if let error = error {
                    print ("\(error)")
                }
                if let response = response {
                    let httpResponse = response as! NSHTTPURLResponse
                    let statusCode = httpResponse.statusCode
                    print("Status code = \(statusCode)")
                }
                if let data = data  {
                    do {
                        let jsonResponse = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions())
                        let binding = jsonResponse["results"]!!["bindings"] as! NSArray
                        for oneBinding in binding {
                            let name = oneBinding["o"]!!["value"] as! NSString
                            var image = oneBinding["p"]!!["value"] as! String
                            image = image.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!
                            let physicst = Physicst(image: image, name: name)
                            if self.physicsts == nil {
                                self.physicsts = [Physicst]()
                            }
                            self.physicsts!.append(physicst)
                        }
                        dispatch_async(dispatch_get_main_queue()) { () -> Void in
                             self.physicstsTableView.reloadData()
                        }
                    }catch _ {
                        print ("not well json-formatted response")
                    }
                }
            })
            task.resume()
        }


override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("physicstCell")! as UITableViewCell
        let row = indexPath.row
        let physicst = self.physicsts![row]
        cell.textLabel?.text = physicst.name as String
        if (physicst.imageData == nil) {
            let session = NSURLSession.sharedSession()
            let url = NSURL(string: physicst.image as String)
            if let url = url {
                let request = NSMutableURLRequest(URL: url)
                let task = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
                    if let data = data {
                        dispatch_async(dispatch_get_main_queue(), { () -> Void in
                            let imageData = UIImage(data: data)
                            cell.imageView?.image = imageData
                            physicst.imageData = imageData
                            self.physicstsTableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.None)
                        })
                    }
                })
                task.resume()
            }else {
                print ("nill URL \(physicst.image)")
            }
        }else {
            cell.imageView?.image = physicst.imageData!
        }
        return cell
    }

TIP

Downloading the images manually for each cell and then loading it to tableViewCell and handling caching in order to improve the performance of scroll is like re inventing the wheel when you have tubless tires availabe :) Please consider using SDWebImage or AFNetworking I have personlly used SDWebImage and its caching feature works perfectly.

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