Reputation: 65
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
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
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