user4376182
user4376182

Reputation: 65

TableViewController does not appear for a few seconds after Transition

I have a tabbarcontroller with four tableviewcontrollers that are connected by navigation controllers. The tableviews are popualted by images and text download from the internet by a XMLParser. When the app loads, after the splash screen, the screen goes black for a few seconds, then the first table view appears. Tab clicks on the other tableviews also lag. How can I display something in place of a black screen or unresponsive interface while the tableview controller's data is downlaoded?

The code of one of the tableviews:

import UIKit

class TopicsTableViewController: UITableViewController, XMLParserDelegate {

var xmlParser : XMLParser!

override func viewDidLoad() {
    super.viewDidLoad()

    let url = NSURL(string: "http://sharontalon.com/feed")
    xmlParser = XMLParser()
    xmlParser.delegate = self
    xmlParser.startParsingWithContentsOfURL(url!)
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


// MARK: XMLParserDelegate method implementation

func parsingWasFinished() {
    self.tableView.reloadData()
}


// MARK: - Table view data source

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

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return xmlParser.arrParsedData.count
}


override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("idCell", forIndexPath: indexPath)


    let currentDictionary = xmlParser.arrParsedData[indexPath.row] as Dictionary<String, String>
    let url = currentDictionary["enclosure"]
    let data = NSData(contentsOfURL: url!.asNSURL) //make sure your image in this url does exist, otherwise unwrap in a if let check

    let description = currentDictionary["description"]


    cell.selectionStyle = UITableViewCellSelectionStyle.None
    cell.textLabel?.text = currentDictionary["title"]
    cell.detailTextLabel?.text = String(htmlEncodedString: description!)
            cell.detailTextLabel?.numberOfLines = 3;
    cell.textLabel?.numberOfLines = 2;

        cell.imageView?.image = UIImage(data: data!)


    return cell
}

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return 80
}


override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    let dictionary = xmlParser.arrParsedData[indexPath.row] as Dictionary<String, String>
    let tutorialLink = dictionary["link"]
    let publishDate = dictionary["pubDate"]

    let tutorialViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("idTutorialViewController") as! TutorialViewController

    tutorialViewController.tutorialURL = NSURL(string: tutorialLink!)
    tutorialViewController.publishDate = publishDate

    showDetailViewController(tutorialViewController, sender: self)

}

Upvotes: 1

Views: 38

Answers (2)

ryantxr
ryantxr

Reputation: 4217

Reloading table data has to be on the main thread of the table to be renewed immediately.

func parsingWasFinished() {
    self.tableView.reloadData()
}

Would be:

func parsingWasFinished() {
    dispatch_async(dispatch_get_main_queue(), {
        self.tableView.reloadData()
    })
}

Upvotes: 0

Dan Beaulieu
Dan Beaulieu

Reputation: 19964

This may be caused by a simple threading issue, give this a shot and if it doesn't work I'll try to help you further:

First move your resource heavy operation to a background thread:

override func viewDidLoad() {
    super.viewDidLoad()

     let url = NSURL(string: "http://sharontalon.com/feed")
     xmlParser = XMLParser()
     xmlParser.delegate = self

    dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0), {
         self.xmlParser.startParsingWithContentsOfURL(url!)
    })
}

Next, move any code that will update the user interface to the foreground thread:

func parsingWasFinished() {
    dispatch_async(dispatch_get_main_queue(), {
        self.tableView.reloadData()
    })
}

If this doesn't resolve your issue, let me know any I'll remove this answer and rethink your problem.

Upvotes: 1

Related Questions