2017-01-16 3 views
0

私のタイトルは、テーブルビュー内の画像がシフトし、テーブルビューをスクロールするときに正しいポストに表示されません。私がスクロールを止めた後、彼らは元の場所に戻っているようです。Firebaseから検索した後にUITableViewでランダムに移動する画像

私は以下の記事のうち、意味を理解しようとしてきた

new Firebase retrieve data and put on the tableview swift

retrieve image from Firebase storage to show on tableview swift

swift Firebase sort posts in tableview by date

しかし、私は絵を表示するようにする方法を見つけ出すことはできませんより良い。 は、ここで私が持っているものです。

import UIKit 
    import FirebaseAuth 
    import FirebaseDatabase 
    import FirebaseStorage 

    class MainFeedTableViewController: UITableViewController { 

     var posts = [Post]() 

     let alert = AlertsViewController() 

     var databaseRef: FIRDatabaseReference! { 
      return FIRDatabase.database().reference() 
     } 

     var storageRef: FIRStorage! { 
      return FIRStorage.storage() 
     } 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     fetchPosts() 

    } 

    // populates the tableView with posts content in real time 
    private func fetchPosts(){ 

     let postRefs = databaseRef.child("posts") 

     postRefs.observe(.value) { (snapshot: FIRDataSnapshot) in 
      var newPost = [Post]() 

      for post in snapshot.children{ 
       let postObject = Post(snapshot: post as! FIRDataSnapshot) 
       newPost.insert(postObject, at: 0) 
      } 

      self.posts = newPost 
      self.tableView.reloadData() 
     } 

    } 

    // MARK: - Table view data source 

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

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

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 

     let postsAtIndexPath = posts[indexPath.row] 

     if postsAtIndexPath.postWithImage == true { 

      let cell = tableView.dequeueReusableCell(withIdentifier: "postWithImage", for: indexPath) as! PostWithImageTableViewCell 

      let postUser = postsAtIndexPath.uid 

      let userRef = databaseRef.child("users/\(postUser!)") 

      userRef.observe(.value, with: { (snapshot) in 

       let user = User(snapshot: snapshot) 

       DispatchQueue.main.async(execute: { 
        cell.userRealNameLabel.text = user.name 
        cell.usernameLabel.text = "@" + user.username 
        cell.postTextView.text = postsAtIndexPath.postText 
        cell.timeStampLabel.text = postsAtIndexPath.date 
       }) 

       self.storageRef.reference(forURL: user.photoURL).data(withMaxSize: 1 * 1024 * 1024, completion: { (data, error) in 

        if error == nil{ 

         DispatchQueue.main.async(execute: { 
          if let data = data{ 
           cell.userProfilePicture.image = UIImage(data: data) 
          } 
         }) 

        } 
        else{ 

         print(error!.localizedDescription) 
        } 
       }) 

       self.storageRef.reference(forURL: postsAtIndexPath.postPictureURL).data(withMaxSize: 1 * 1024 * 1024, completion: { (data, error) in 

        if error == nil{ 

         DispatchQueue.main.async(execute: { 
          if let data = data{ 
           cell.postImage.image = UIImage(data: data) 

          } 
         }) 

        } 
        else{ 
         self.alert.displayAlert(alertTitle: "Error", alertMessage: error!.localizedDescription, fromController: self) 
        } 
       }) 

      }) { (error) in 
       self.alert.displayAlert(alertTitle: "Error", alertMessage: error.localizedDescription, fromController: self) 
      } 

      return cell 
     } 
     else{ 

      let cell = tableView.dequeueReusableCell(withIdentifier: "postWithText", for: indexPath) as! PostTableViewCell 

      let postUser = postsAtIndexPath.uid 

      let userRef = databaseRef.child("users/\(postUser!)") 

      userRef.observe(.value, with: { (snapshot) in 

       let user = User(snapshot: snapshot) 

       DispatchQueue.main.async(execute: { 
        cell.userRealNameLabel.text = user.name 
        cell.usernameLabel.text = "@" + user.username 
        cell.postTextView.text = postsAtIndexPath.postText 
        cell.timestampLabel.text = postsAtIndexPath.date 

       }) 

       self.storageRef.reference(forURL: user.photoURL).data(withMaxSize: 1 * 1024 * 1024, completion: { (data, error) in 

        if error == nil{ 

         DispatchQueue.main.async(execute: { 
          if let data = data{ 
           cell.userProfilePicture.image = UIImage(data: data) 
          } 
         }) 

        } 
        else{ 

         print(error!.localizedDescription) 
        } 
       }) 

      }) { (error) in 
       self.alert.displayAlert(alertTitle: "Error", alertMessage: error.localizedDescription, fromController: self) 
      } 

      return cell 
     } 

    } 

} 

私は苦労していた理由私は、彼らが自分の情報を編集するときにユーザーのユーザー名、名前、およびプロフィールの写真はどこでも、リアルタイムで変更したいので、それはです。だからこそ私は、投稿のユーザーIDに基づいてユーザー情報を取得しています。

これを実装するにはどうすればよいでしょうか?

答えて

2

prepareForReuse関数をPostWithImageTableViewCellに上書きする必要があります。

override func prepareForReuse() { 
     super.prepareForReuse() 
     self.userProfilePicture.image = nil 
     //reset the rest of the values on your `UITableViewCell` subclass 
} 

EDIT

再利用の問題が解決されましたので、私はより便利な画像表示の経験のために、Kingfisher、次のキャッシングフレームワークをお勧めしたいと思います。

キングフィッシャーは、UIImageViewの拡張機能があります。どのようなものがあなたのキャッシュを担当しますか?あなたはそれを使用する方法をここで

:あなたが唯一のURLに設定

let url = URL(string: "https://domain.com/image.jpg")! 
imageView.kf.setImage(with: url) 

は、何が一意に一度だけ画像リソースを識別し、ダウンロードします。ここにはcheat sheetの使い方があります。

+0

大丈夫ですが、今はスクロールするたびに写真が読み込まれているように見えるので、スクロールして表示されます。それらをリロードせずに、既に表示されている写真をロードしたままにする方法はありますか? idkの場合はもちろん意味がある –

+0

。セルの表示から独立して画像のダウンロードを開始する。画像を保存するための何らかのキャッシュを導入し、一度だけダウンロードすることができます。 – dirtydanee

+0

あなたはその事例を何時でも持っていますか? –

関連する問題