2016-06-25 9 views
0

これにいくつか類似の質問があることを認識しています。しかし、私がチェックしたものは間違った言葉か、私が探していたものではなかったので、私は新しい質問をしています。参考までに、私はSwift 2でXCode 7.3.1を使用しています。スクロール時にUITableViewが遅れます

新しいiOSアプリケーションの1つの機能は、インターネットでデータを検索し、その結果をUITableViewに取り込むことです。私の問題は、各セルに画像を表示することで、スクロールが非常に面倒になります。

私の理想的な解決方法は、デフォルトの画像表示を使用し、ユーザーがスクロールを継続できるようにする一方、バックグラウンドでダウンロードすることです。そして、一度検索すると、デフォルトに置き換わります。私はこれを行う方法についていくつかの以前の答えを見たが、誰も私のために働いていない。

P.S. WITH SWIFTの問題を解決する別の質問が表示された場合は、URLを投稿すれば削除されます。ここで

は(遅れて)私が現在使用しているコードです:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { // Creates each cell, by parsing through the data received from the Employees array which we returned from the database 
    if (Employees.count == 0) 
    { 
     let cell = self.ResultsTable.dequeueReusableCellWithIdentifier("NORESULT", forIndexPath: indexPath) as! TruckSearchNRTableViewCell 

     return cell 
    } 

    else { 
     let cell = self.ResultsTable.dequeueReusableCellWithIdentifier("RESULT", forIndexPath: indexPath) as! TruckSearchTableViewCell 

      cell.companyLabel.text = Employees[indexPath.row]["CompanyName"] as? String 
      cell.nameLabel.text = Employees[indexPath.row]["EmployeeName"] as? String 
     if let mobile = Employees[indexPath.row]["PhoneNumber"] as? String { 
      if (mobile == "") 
      { 
       cell.mobileLabel.hidden = true 
       cell.mobileTitle.hidden = true 
      } else { 
       cell.mobileTitle.hidden = false 
       cell.mobileLabel.hidden = false 
      } 
      let phonenumber = mobile.stringByReplacingOccurrencesOfString("[^0-9]", withString: "", options: NSStringCompareOptions.RegularExpressionSearch, range:nil); 
      cell.phoneNumber.text = phonenumber 
     } 
      cell.titleLabel.text = Employees[indexPath.row]["JobTitle"] as? String 
      cell.truckLabel.text = Employees[indexPath.row]["TruckNumber"] as? String 
      cell.supervisorLabel.text = Employees[indexPath.row]["SupervisorName"] as? String 
     if (Employees[indexPath.row]["Synced"] as? Int) == 0 { 
      turnRed(cell) 
     } else { 
      turnBlack(cell) 
     } 
     if let ePhoto = Employees[indexPath.row]["PicLocation"] as? String { // Save complete URL of picture location, and save it to the table 

      let url = NSURL(string: "https://exampleurl.com/\(ePhoto)")! 
      if let data = NSData(contentsOfURL: url){ 
       let myImage = UIImage(data: data) 
       cell.employeePhoto.image = myImage 
      } 
      else 
      { 
       cell.employeePhoto.image = UIImage(named: "person-generic") 
      } 

     } 

     return cell 
    } 
} 
+1

は、[この]をご覧ください(http://stackoverflow.com/ A/26147814/1611876)溶液が挙げられる。 ObjCにありますが、それをSwiftに変換するのは簡単な作業です。また、毎回すべてのイメージをダウンロードすることを避けるためのキャッシュメカニズムが必要です。 [SDWebImage](https://github.com/rs/SDWebImage)は、あなたが達成したいと思うもののための良い解決策であり、**バックグラウンドのダウンロード/キャッシュ/プレースホルダーイメージ**を使用できる状態にします。 – vhristoskov

+0

私はチャンスを得るとき、それを調べるよ、ありがとう! –

答えて

2

問題は、あなたがそれをブロックしているメインスレッド、上の画像を取得しているということです。スクロールを含むすべてのUI操作はメインスレッド上で実行されるので、その時点では不安定になっています。

if let data = NSData(contentsOfURL: url){ 

    let myImage = UIImage(data: data) 
    cell.employeePhoto.image = myImage 

} else { 

    cell.employeePhoto.image = UIImage(named: "person-generic") 

} 

バックグラウンドスレッドで画像要求を入れて、再びメインスレッド上に画像を設定します。これを解決するため、代わりにする

例:

let qos = QOS_CLASS_USER_INITIATED 

dispatch_async(dispatch_get_global_queue(qos, 0), { 

    if let data = NSData(contentsOfURL: url){ 

     let myImage = UIImage(data: data) 

     dispatch_async(dispatch_get_main_queue(), { 
      cell.employeePhoto.image = myImage 
     }) 

    } else { 

     dispatch_async(dispatch_get_main_queue(), { 
      cell.employeePhoto.image = UIImage(named: "person-generic") 
     }) 

    } 

}) 

代わりにあなたがそうのようなデータを取得するために、非同期URLのセッションを使用することができます。

let request: NSURLRequest = NSURLRequest(URL: url) 
let mainQueue = NSOperationQueue.mainQueue() 

NSURLConnection.sendAsynchronousRequest(request, queue: mainQueue, completionHandler: { (response, data, error) -> Void in 

    if error == nil { 

     let myImage = UIImage(data: data) 

     dispatch_async(dispatch_get_main_queue(), { 
      cell.employeePhoto.image = myImage 
     }) 

    } else { 

     dispatch_async(dispatch_get_main_queue(), { 
      cell.employeePhoto.image = UIImage(named: "person-generic") 
     }) 

    } 

}) 
+0

それはまだかなり不安定です、それは十分速く細胞を返すことができないかもしれませんか? –

+0

申し訳ありませんが、私は自分の電話でそれを書いていましたが、elseステートメントを逃しました。私の編集したコードを試して、それがうまくいくかどうか教えてください。あなたのコードから判断すると、処理速度の問題ではありません。 –

+0

メインスレッドで画像データをデコードしないように、バックグラウンドスレッドで 'image.CGImage'にアクセスする必要があります。さらに、細胞が再利用されるので、この答えは間違ったイメージを一時的に現われるでしょう。 –

関連する問題