2017-09-15 20 views
1

私は、ユーザーが投稿を好きになるかもしれないコレクションビューを実装しようとしましたが、何らかの理由でユーザーがフィードを更新するだけで、行ってはならない古い細胞を残す。つまり、セルの半分は更新され、残りの半分は古い値になります。基本的には、問題なく現在のセルを単に更新する方法を知ることはできません。理想的には、ユーザーがlikeボタンを押して、そのボタンが「違う」に変わり、collectionviewで変更される投稿の好きな人の数が増えることを、私は望みます。ここでUICollectionViewセルをリロードして古いセルをリロードしない

は、コレクションビューのセルをロードするためのコードです:ここで

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
    let cell = feedCollectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as! MyGroupFeedCollectionViewCell 

    cell.postKey = feedArray[indexPath.row].postKey 

    //clears the cells first 
    cell.profileImage.image = nil 
    cell.usernameLabel.text = nil 
    cell.usernameLabel2.text = nil 
    cell.groupName.text = nil 
    cell.postImageView.image = nil 
    cell.postCaptionTextView.text = nil 
    cell.timeStamp.text = nil 

    //load profile picture 
    cell.profileImage.sd_setImage(with: URL(string: feedArray[indexPath.row].ProfilePic), placeholderImage: UIImage(named:"no profile picture.png")) 

    //load username 
    cell.usernameLabel.text = feedArray[indexPath.row].Username 
    cell.usernameLabel2.text = feedArray[indexPath.row].Username 

    //load groupName when in home feed 
    cell.groupName.text = feedArray[indexPath.row].GroupName 

    //load postImage 
    cell.postImageView.sd_setImage(with: URL(string: feedArray[indexPath.row].PostImage), placeholderImage: UIImage(named:"penguinPanorama")) 

    //load caption 
    cell.postCaptionTextView.text = feedArray[indexPath.row].caption 

    //load likes once likes are implemented 
    //checks if the user has liked the post or not 
    databaseRef.child("likes").child((FIRAuth.auth()?.currentUser?.uid)!).child(feedArray[indexPath.row].postKey).observe(.value, with: { (snapshot) in 
     if(snapshot.exists()) 
     { 
      cell.liked = "Yes" 
      cell.likeButton.setTitle("Unlike", for: .normal) 
     } 
     else{ 
      cell.liked = "No" 
      cell.likeButton.setTitle("Like", for: .normal) 
     } 
    }) 

のようなボタンが押されている関数のコードです:同類のために

@IBAction func likeButton_tapped(_ sender: Any) { 
    self.likeButton.isEnabled = false 
    print(self.postKey) 
    print(self.liked) 

    //make it so liking or unliking adds or subtracts from the total number of likes on the post 
    if liked == "Yes" 
    { 
     self.databaseRef.child("likes").child((FIRAuth.auth()?.currentUser?.uid)!).child(self.postKey).removeValue() 

     let NewLikeNumber = likeNumber - 1 
     self.databaseRef.child("GroupPosts").child(self.groupName.text!).child(self.postKey).child("likes").setValue(NewLikeNumber) 
     print(NewLikeNumber) 
    } 
    else{ 
     self.databaseRef.child("likes").child((FIRAuth.auth()?.currentUser?.uid)!).child(self.postKey).setValue("") 

     let NewLikeNumber = likeNumber + 1 
     self.databaseRef.child("GroupPosts").child(self.groupName.text!).child(self.postKey).child("likes").setValue(NewLikeNumber) 
     print(NewLikeNumber) 
    } 

    self.likeButton.isEnabled = true 
} 
+0

ここで、コレクションビューを再読み込みしていますか? – ebby94

+0

@ ebby94投稿がロードされている関数の最後にコレクションビューをリロードしています。この関数はviewwillで表示されます – dombad

答えて

0

、私はお勧めしますFirebaseのトランザクションを使用しているので、あなたの数が同時に変更されて混乱することになります。

func likePost(_ post: Post, completion: @escaping() ->()) { 

    guard let currentUserId = Auth.auth().currentUser?.uid else { 
     return 
    } 

    databaseRef.child(likes).child(currentUserId).child(postKey).runTransactionBlock ({ (currentData: MutableData) -> TransactionResult in 

       if var data = currentData.value as? [String: Any] { 
        var count = data["likesCount"] as! Int 
        count += 1 
        data["likesCount"] = count 
        currentData.value = data 
        return TransactionResult.success(withValue: currentData) 
       } 

       return TransactionResult.success(withValue: currentData) 

    }, andCompletionBlock: { (error, success, snapshot) in 

       // ... 

    }) 

} 

そしてもちろん、同じことが、ユーザーが投稿を好まない場合にも起こります。今、ユーザーがポストを好きかどうかを知るために、あなたはローカルのような状態を保存するために、あなたのクラスにブール値を作成することができ

private var isPostLiked = false 

そしてたびのようなユーザーがボタンをタップし、実行しますそのような単純なチェック:今

 func handleLikeTapped() { 

      guard let post = post else { 
       return 
      } 

      if isPostLiked { 

       NetworkManager.shared.likePost(post, completion: { [weak self] in 

        // Once the completion handler of your method is called, the likes count in your database is now updated. 
        // To avoid making another read in the database just now, you can just 
        // Update your count (a label that shows how many likes a specific post received I guess ?) locally here so that the user can see in realtime the change (with animation or not depending on what you want to achieve) 

        // And finally update the like state of the post so that if the user click again on like it wouldn't mess everything up: 

        self?.isPostLiked = false 
       }) 

      } 

      else { 

       NetworkManager.shared.dislikePost(post, completion: { [weak self] in 

        // ... 
       }) 
      } 
    } 

はもちろん、後であなたが好きは異なるビューコントローラでカウントアクセスする必要がある場合、あなたは自分のデータベースから更新likesCountを取得するためにobserveSingleEvent(of: .value)を使用します。

質問がありましたらお知らせください。

関連する問題