删除 tableView 单元格并从 firebase 中删除数据

Posted

技术标签:

【中文标题】删除 tableView 单元格并从 firebase 中删除数据【英文标题】:Delete tableView cell and remove data from firebase 【发布时间】:2020-09-19 11:55:26 【问题描述】:

我正在研究社交网络的项目。卡在从 Firebase 数据库中删除用户 cmets 的阶段。要删除特定评论,我需要知道评论 ID,但我不明白如何访问它。非常感谢您对此提供的任何帮助!

Firebase 数据库示例:

评论视图控制器:

class CommentViewController: UIViewController 

@IBOutlet weak var sendButton: UIButton!
@IBOutlet weak var commentTextField: UITextField!
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var constraintToBottom: NSLayoutConstraint!

var postId: String!
var comments = [Comment]()
var users = [User]()

override func viewDidLoad() 
    super.viewDidLoad()
    tableView.dataSource = self
    title = "Comment"
    tableView.estimatedRowHeight = 77
    tableView.rowHeight = UITableView.automaticDimension
    empty()
    handleTextField()
    loadComments()
    
    NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil)
    
    NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil)


override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) 
    view.endEditing(true)



@objc func keyboardWillShow(_ notification: NSNotification) 
    let keyboardFrame = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as AnyObject).cgRectValue
    UIView.animate(withDuration: 0.3) 
        self.constraintToBottom.constant = keyboardFrame!.height
        self.view.layoutIfNeeded()
    


@objc func keyboardWillHide(_ notification: NSNotification) 
    UIView.animate(withDuration: 0.3) 
        self.constraintToBottom.constant = 0
        self.view.layoutIfNeeded()
    


var comment: Comment?


func loadComments() 
    Api.Post_Comment.REF_POST_COMMENTS.child(self.postId).observe(.childAdded, with: 
        snapshot in
        Api.Comment.observeComments(withPostId: snapshot.key, completion: 
            comment in
            self.fetchUser(uid: comment.uid!, completed: 
                self.comments.append(comment)
                self.tableView.reloadData()
                
            )
        )
    )



func fetchUser(uid: String, completed: @escaping() -> Void ) 
    
    Api.User.observeUser(withId: uid, completion: 
        user in
        self.users.append(user)
        completed()
    )



func handleTextField() 
    commentTextField.addTarget(self, action: #selector(self.textFieldDidChange), for: UIControl.Event.editingChanged)


@objc func textFieldDidChange() 
    if let commentText = commentTextField.text, !commentText.isEmpty 
        sendButton.setTitleColor(UIColor.black, for: UIControl.State.normal)
        sendButton.isEnabled = true
        return
    
    sendButton.setTitleColor(UIColor.lightGray, for: UIControl.State.normal)
    sendButton.isEnabled = false


override func viewWillAppear(_ animated: Bool) 
    super.viewWillAppear(animated)
    self.tabBarController?.tabBar.isHidden = true



override func viewWillDisappear(_ animated: Bool) 
    super.viewWillDisappear(animated)
    self.tabBarController?.tabBar.isHidden = false


@IBAction func sendButton_TouchUpInside(_ sender: Any) 
    let commentsReference = Api.Comment.REF_COMMENTS
    let newCommentId = commentsReference.childByAutoId().key!
    let newCommentReference = commentsReference.child(newCommentId)
    
    guard let currentUser = Api.User.CURRENT_USER else 
        return
    
    let currentUserId = currentUser.uid
    newCommentReference.setValue(["uid": currentUserId, "commentText": commentTextField.text!], withCompletionBlock: 
        (error, ref) in
        if error != nil 
            ProgressHUD.showError(error!.localizedDescription)
            return
        
        let postCommentRef = Api.Post_Comment.REF_POST_COMMENTS.child(self.postId).child(newCommentId)
        postCommentRef.setValue(true, withCompletionBlock:  (error, ref) in
            if error != nil 
                ProgressHUD.showError(error!.localizedDescription)
                return
            
        )
        self.empty()
        self.view.endEditing(true)
    )



func empty() 
    self.commentTextField.text = ""
    sendButton.setTitleColor(UIColor.lightGray, for: UIControl.State.normal)
    sendButton.isEnabled = false


override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
    if segue.identifier == "Comment_ProfileSegue" 
        let profileVC = segue.destination as! ProfileUserViewController
        let userId = sender as! String
        profileVC.userId = userId
    




extension CommentViewController: UITableViewDataSource 
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return comments.count

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCell(withIdentifier: "CommentCell", for: indexPath) as! CommentTableViewCell
    let comment = comments[indexPath.row]
    let user = users[indexPath.row]
    cell.comment = comment
    cell.user = user
    cell.delegate = self
    return cell


func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool 
    return true


func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) 
    if (editingStyle == .delete) 
        

        
        
    

CommentTableViewCell:

class CommentTableViewCell: UITableViewCell 
@IBOutlet weak var profileImageView: UIImageView!
@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var commentLabel: UILabel!

var delegate: CommentTableViewCellDelegate?
var comment: Comment? 
    didSet 
        updateView()
    



var user: User? 
    didSet 
        setupUserInfo()
    
 

func updateView() 
    commentLabel.text = comment?.commentText



func setupUserInfo() 
    nameLabel.text = user?.username
    if let photoUrlString = user?.profileImageUrl 
        let photoUrl = URL(string: photoUrlString)
        profileImageView.sd_setImage(with: photoUrl, placeholderImage: UIImage(named: "photo_placeholder"))
    


override func awakeFromNib() 
    super.awakeFromNib()
    nameLabel.text = ""
    commentLabel.text = ""
    let tapGestureForNameLabel = UITapGestureRecognizer(target: self, action: #selector(self.nameLabel_TouchUpInside))
    nameLabel.addGestureRecognizer(tapGestureForNameLabel)
    nameLabel.isUserInteractionEnabled = true


@objc func nameLabel_TouchUpInside() 
    if let id = user?.id 
        delegate?.goToProfileUserVC(userId: id)
    


override func prepareForReuse() 
    super.prepareForReuse()
    profileImageView.image = UIImage(named: "placeholderImg")


override func setSelected(_ selected: Bool, animated: Bool) 
    super.setSelected(selected, animated: animated)

    // Configure the view for the selected state

评论接口

class CommentApi 
var REF_COMMENTS =  Database.database().reference().child("comments")

func observeComments(withPostId id: String, completion: @escaping (Comment) -> Void) 
    REF_COMMENTS.child(id).observeSingleEvent(of: .value, with: 
        snapshot in
        if let dict = snapshot.value as? [String: Any] 
            let newComment = Comment.transformComment(dict: dict, key: snapshot.key)
            completion(newComment)
        
    )


func observeComment(withId id: String, completion: @escaping (Comment) -> Void) 
    REF_COMMENTS.child(id).observeSingleEvent(of: DataEventType.value, with: 
        snapshot in
        if let dict = snapshot.value as? [String: Any] 
            let comment = Comment.transformComment(dict: dict, key: snapshot.key)
            completion(comment)
        
    )

评论模型:

class Comment 
var commentText: String?
var uid: String?
var id: String?

 extension Comment 
static func transformComment(dict: [String: Any], key: String) -> Comment 
    let comment = Comment()
    comment.id = key
    comment.commentText = dict["commentText"] as? String
    comment.uid = dict["uid"] as? String
    return comment

【问题讨论】:

我认为您应该重组您的 firebase 数据库,以便在帖子中您可以找到使用他们的 ID 对该帖子发表评论的用户。当您想删除特定评论时,使用用户 ID 在帖子中访问他的 cmets,然后轻松删除您想要的评论。 【参考方案1】:

概括地说,您的 tableView 由 dataSource 支持,通常是一个数组,它是 tableView 中显示的内容的来源。

var userCommentArray = [UserComment]()

您应该从 Firebase 加载数据并将该数据作为 UserComment 对象存储在数组中

class UserComment 
   var firebaseKey = ""
   var commentText = ""
   var uid = ""

firebase_key 属性是 Firebase 中节点的键,在截图中显示为-MH_xxxx,commentText 和 uid 是该节点的子数据。

数组中元素的索引匹配 tableView 中显示的内容,因此 row0 匹配数组索引 0,row 1 匹配数组索引 1 等等。

当用户删除第 1 行时,您知道这是数组中的索引 1。读取对象,获取它的 firebaseKey,然后将其从 firebase 中删除,相应地更新数组,然后重新加载您的 UI。

有关该过程的详细信息,请参阅我对您的 Other Question 的回答。

【讨论】:

以上是关于删除 tableView 单元格并从 firebase 中删除数据的主要内容,如果未能解决你的问题,请参考以下文章

从数据库中删除记录

从列表中搜索多个条件的单元格并从列表中返回相应的值

如果值> 1,则在下面插入空白单元格并从上面的单元格复制/粘贴值的宏

目标 C:如何突出显示 tableView 单元格并在重新加载表格时保持突出显示?

选择特定范围的单元格并仅删除突出显示的单元格并向上移动的 VBA

如何移动表格单元格并显示图像?