2016-07-03 15 views
0

Ich versuche, Bilder, die aus der Web-URL extrahiert wurden, in die Bildansicht jeder Zelle zu laden.Langsames Laden von Bildern in UITableViewController, extrahiert aus URL-String

Wenn jedoch i blättern in der Tabelle auf dem Bildschirm, wie ich es glauben friert versucht, die Bilder für jede Zelle 1 von 1.

Gibt es eine Weise, die ich es asynchron machen zu greifen? Die zur Verfügung stehenden Ressourcen gibt derzeit veraltete oder inkompatible (Lauf obj c), wie ich laufen auf Swift 2

Der entsprechende Code, den ich in der Tabelle View-Controller bin mit unter:

override func tableView(newsFeedTableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) 
    let blogPost: BlogPost = blogPosts[indexPath.row] 
    cell.textLabel?.text = blogPost.postTitle 
    let unformattedDate = blogPost.postDate 
    //FORMATTING: Splitting of raw data into arrays based on delimiter '+" to print only useful information 
    let postDateArr = unformattedDate.characters.split{$0 == "+"}.map(String.init) 
    cell.detailTextLabel?.text = postDateArr[0] 
    let url = NSURL(string: blogPost.postImageUrl) 
    let data = NSData(contentsOfURL: url!) 
    cell.imageView!.image = UIImage(data: data!)//WHY SO SLOW!? 

    print(blogPost.postImageUrl) 

    return cell 
} 
+0

Haben Sie versucht, mit 'DataTaskWithRequest'? Dadurch wird Ihr Ladevorgang vollständig "Asynchron" und Ihre Benutzeroberfläche wird nicht eingefroren. Sie können auch [Alamofire] (https://github.com/Alamofire/Alamofire) verwenden, um asynchrone Aufrufe zu erstellen. Hör zu. – Dershowitz123

Antwort

0

Try dies

var image: UIImage 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {() -> Void in 
      // Background thread stuff. 
      let url = NSURL(string: blogPost.postImageUrl) 
      let data = NSData(contentsOfURL: url!) 
      image = UIImage(data:data) 

      dispatch_async(dispatch_get_main_queue(), {() -> Void in 
       // Main thread stuff. 
       cell.imageView.image = image 
      }) 
     }) 
+0

große Antwort! Vielen Dank ! :) –

+0

Es ist besser, wenn Sie 'Alamofire' versuchen – Proton

0

Lets reinigen Sie Ihren Code ein bisschen. Zuerst versuchen Sie, alle Ihre Zellen in Ihrem ViewController zu deklarieren. Das bedeutet, dass Ihre App nicht versucht, jedes Bild einzeln, sondern mehr wie alles zusammen zu laden.

Sie müssen eine separate Datei namens PostCell erstellen, die eine Art von UITableViewCell sein wird.

Dann müssen Sie zu Ihrer Prototypzelle gehen und diese Ansichtselemente mit dieser PostCell verbinden, genau so, wie Sie diese zu einem anderen ViewController hinzufügen würden.

Hier ist nun, neue Code in Ihre cellForRowAtIndexPath Funktion:

override func tableView(newsFeedTableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    let blogPost = blogPosts[indexPath.row] 

    if let cell = tableView.dequeueReusableCellWithIdentifier("Cell") as? PostCell { 
    cell.configureCell(blogPost) 

    return cell 
    } 

    return UITableViewCell() // You need to do this because of if let 
} 

Und declear dies auf diesem PostCell:

func configureCell(post: BlogPost) { 
    this.textLabel.text = post.postTitle 
    let postDateArr = unformattedDate.characters.split{$0 == "+"}.map(String.init) 
    this.detailTextLabel.text = postDateArr[0] 

    // I would add few if let declarations here too, but if you are sure all these forced ! variables do exciest, then its ok 
    let url = NSURL(string: blogPost.postImageUrl) 
    let data = NSData(contentsOfURL: url!) 
    this.imageView.image = UIImage(data: data!) 
} 

Oder etwas in diese Richtung. Wenn Sie diese Elemente mit Ihrer Zelle verbinden, erhalten Sie geeignete Variablennamen für diese.

Das sollte helfen. Es gibt viele Tutorials, wie man eine benutzerdefinierte Tabellenansichtszelle erstellt. Einige von ihnen raten, alle Deklarationen in diesen cellForRowAtIndexPath zu setzen, aber ich habe festgestellt, dass es sehr schnell problematisch wird.

Also ... mein Rat in einer Nusszelle ... erstellen Sie eine benutzerdefinierte Tableviewcell.

Hoffe, das hilft! :)

0

Um das Bild in jede Zelle zu laden, verwenden Sie die SDWebImage Third-Party-Bibliothek. Sie können es unter Verwendung von Pods als Put Pod 'SDWebImage' Es bietet verschiedene Methoden, um das Bild mit Zwischenspeichern oder ohne Zwischenspeichern asynchron laden. Beim Caching müssen Sie sich nicht wirklich darum sorgen, dass jedes Mal, wenn eine Zelle auf dem Bildschirm angezeigt wird, Bilddaten geladen werden. Versuchen Sie diese

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

    if let cell = tableView.dequeueReusableCellWithIdentifier("Cell") as? PostCell { 
    --reset your cell here-- 
    // cell.imageView.image = nil 
    } 
    cell.imageView.sd_setImageWithURL(YOUR_URL, placeholderImage: UIImage(named: "")) { 
    (UIImage img, NSError err, SDImageCacheType cacheType, NSURL imgUrl) -> Void in 
     // Do awesome things 
    } 
-- configure your cell here -- 
} 
Verwandte Themen