table 视图单元格中的按钮没有响应

Button in table view cell not responding

我正在开发一个社交媒体应用程序,在主要部分(新闻)中,我创建并添加了一个 UITableViewController 自定义 PostCell。在这个单元格中我添​​加了一个赞UIButton。问题是当我点击按钮时,#selector 方法没有响应。

这是我的一些代码:

Post 单元格:

import UIKit

class PostCell: UITableViewCell {
    
    let userDataContainerView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()
    
    let userImgView: UIImageView = {
        let iv = UIImageView()
        iv.translatesAutoresizingMaskIntoConstraints = false
        iv.image = UIImage(named: "person.crop.circle.fill")?.maskWithColor(color: UIColor.mainColor)
        return iv
    }()
    
    let completeNameLabel: UILabel = {
        let lbl = UILabel()
        lbl.translatesAutoresizingMaskIntoConstraints = false
        lbl.font = UIFont.systemFont(ofSize: 18, weight: .semibold)
        lbl.textColor = UIColor.darkText
        lbl.adjustsFontSizeToFitWidth = true
        return lbl
    }()
    
    let usernameLabel: UILabel = {
        let lbl = UILabel()
        lbl.translatesAutoresizingMaskIntoConstraints = false
        lbl.font = UIFont.systemFont(ofSize: 16, weight: .medium)
        lbl.textColor = UIColor.darkGray
        lbl.adjustsFontSizeToFitWidth = true
        return lbl
    }()
    
    let timestampLabel: UILabel = {
        let lbl = UILabel()
        lbl.translatesAutoresizingMaskIntoConstraints = false
        lbl.font = UIFont.systemFont(ofSize: 14, weight: .regular)
        lbl.textColor = UIColor.gray
        lbl.adjustsFontSizeToFitWidth = true
        return lbl
    }()
    
    let moreOptionsButton: UIButton = {
        let button = UIButton()
        button.translatesAutoresizingMaskIntoConstraints = false
        button.setImage(UIImage(systemName: "ellipsis"), for: .normal)
        button.tintColor = UIColor.mainColor
        button.contentVerticalAlignment = .fill
        button.contentHorizontalAlignment = .fill
        return button
    }()
    
    let textViewsContainerView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()
    
    let textViewSeparatorView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.backgroundColor = UIColor.black
        return view
    }()
    
    let postTextView: UITextView = {
        let tv = UITextView()
        tv.translatesAutoresizingMaskIntoConstraints = false
        tv.isEditable = false
        tv.font = UIFont.systemFont(ofSize: 22, weight: .medium)
        tv.adjustsFontForContentSizeCategory = true
        tv.layer.masksToBounds = true
        tv.layer.cornerRadius = 16
        tv.layer.borderWidth = 0.5
        tv.layer.borderColor = CGColor.mainColor
        return tv
    }()
    
    let resourceTextView: UITextView = {
        let tv = UITextView()
        tv.translatesAutoresizingMaskIntoConstraints = false
        tv.isEditable = false
        tv.font = UIFont.systemFont(ofSize: 18, weight: .medium)
        tv.adjustsFontForContentSizeCategory = true
        tv.layer.masksToBounds = true
        tv.layer.cornerRadius = 16
        tv.layer.borderWidth = 0.5
        tv.layer.borderColor = CGColor.mainColor
        tv.isSelectable = true
        return tv
    }()
    
    let actionsContainerView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()
    
    let likeButton: UIButton = {
        let button = UIButton()
        button.isUserInteractionEnabled = true
        button.translatesAutoresizingMaskIntoConstraints = false
        button.setImage(UIImage(systemName: "hand.thumbsup"), for: .normal)
        button.tintColor = UIColor.mainColor
        button.contentVerticalAlignment = .fill
        button.contentHorizontalAlignment = .fill
        button.imageEdgeInsets = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
        return button
    }()
    
    let likesLabel: UILabel = {
        let lbl = UILabel()
        lbl.translatesAutoresizingMaskIntoConstraints = false
        lbl.text = "0"
        lbl.textColor = UIColor.mainColor
        lbl.font = UIFont.systemFont(ofSize: 16, weight: .medium)
        lbl.adjustsFontSizeToFitWidth = true
        return lbl
    }()
    
    let commentsButton: UIButton = {
        let button = UIButton()
        button.translatesAutoresizingMaskIntoConstraints = false
        button.setImage(UIImage(systemName: "bubble.left"), for: .normal)
        button.tintColor = UIColor.mainColor
        button.contentVerticalAlignment = .fill
        button.contentHorizontalAlignment = .fill
        button.imageEdgeInsets = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
        return button
    }()

    let bookmarkButton: UIButton = {
        let button = UIButton()
        button.translatesAutoresizingMaskIntoConstraints = false
        button.setImage(UIImage(systemName: "bookmark"), for: .normal)
        button.tintColor = UIColor.mainColor
        button.contentVerticalAlignment = .fill
        button.contentHorizontalAlignment = .fill
        button.imageEdgeInsets = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
        return button
    }()
    
    override func layoutSubviews() {
        super.layoutSubviews()
        userImgView.circleImageView()
    }
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: .default, reuseIdentifier: reuseIdentifier)
        self.selectionStyle = .none
        addSubview(userDataContainerView)
        userDataContainerView.addSubview(userImgView)
        userDataContainerView.addSubview(completeNameLabel)
        userDataContainerView.addSubview(usernameLabel)
        userDataContainerView.addSubview(moreOptionsButton)
        addSubview(textViewsContainerView)
        addSubview(textViewSeparatorView)
        textViewsContainerView.addSubview(postTextView)
        textViewsContainerView.addSubview(resourceTextView)
        addSubview(actionsContainerView)
        actionsContainerView.addSubview(likeButton)
        actionsContainerView.addSubview(likesLabel)
        actionsContainerView.addSubview(commentsButton)
        actionsContainerView.addSubview(bookmarkButton)
        actionsContainerView.addSubview(timestampLabel)
        setUpConstraints()
    }
    
    func setUpConstraints() {
        // needs x, y, h, w anchors
        userDataContainerView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        userDataContainerView.topAnchor.constraint(equalTo: self.topAnchor, constant: 8).isActive = true
        userDataContainerView.heightAnchor.constraint(equalTo: self.heightAnchor, multiplier: 1/5).isActive = true
        userDataContainerView.widthAnchor.constraint(equalTo: self.widthAnchor).isActive = true
        
        // needs x, y, h, w anchors
        userImgView.leftAnchor.constraint(equalTo: userDataContainerView.leftAnchor, constant: 8).isActive = true
        userImgView.topAnchor.constraint(equalTo: userDataContainerView.topAnchor, constant: 8).isActive = true
        userImgView.heightAnchor.constraint(equalTo: userDataContainerView.heightAnchor, constant: -16).isActive = true
        userImgView.widthAnchor.constraint(equalTo: userImgView.heightAnchor).isActive = true
        
        // needs x, y, h, w anchors
        completeNameLabel.leftAnchor.constraint(equalTo: userImgView.rightAnchor, constant: 8).isActive = true
        completeNameLabel.topAnchor.constraint(equalTo: userDataContainerView.topAnchor, constant: 4).isActive = true
        completeNameLabel.heightAnchor.constraint(equalTo: userDataContainerView.heightAnchor, multiplier: 1/2, constant: -8).isActive = true
        completeNameLabel.widthAnchor.constraint(equalTo: userDataContainerView.widthAnchor, multiplier: 1/2).isActive = true
        
        // needs x, y, h, w anchors
        usernameLabel.leftAnchor.constraint(equalTo: userImgView.rightAnchor, constant: 8).isActive = true
        usernameLabel.topAnchor.constraint(equalTo: completeNameLabel.bottomAnchor, constant: 4).isActive = true
        usernameLabel.heightAnchor.constraint(equalTo: userDataContainerView.heightAnchor, multiplier: 1/2, constant: -8).isActive = true
        usernameLabel.widthAnchor.constraint(equalTo: userDataContainerView.widthAnchor, multiplier: 1/2).isActive = true
        
        // needs x, y, w, anchors
        moreOptionsButton.rightAnchor.constraint(equalTo: userDataContainerView.rightAnchor, constant: -16).isActive = true
        moreOptionsButton.topAnchor.constraint(equalTo: userDataContainerView.topAnchor, constant: 16).isActive = true
        moreOptionsButton.heightAnchor.constraint(equalTo: userImgView.heightAnchor, multiplier: 1/4, constant: -4).isActive = true
        moreOptionsButton.widthAnchor.constraint(equalTo: userImgView.heightAnchor, multiplier: 2/3).isActive = true
        
        // needs x, y, h, w anchors
        textViewSeparatorView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        textViewSeparatorView.bottomAnchor.constraint(equalTo: userDataContainerView.bottomAnchor).isActive = true
        textViewSeparatorView.heightAnchor.constraint(equalToConstant: 0.5).isActive = true
        textViewSeparatorView.widthAnchor.constraint(equalTo: self.widthAnchor).isActive = true
        
        // needs x, y, h, w anchors
        textViewsContainerView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        textViewsContainerView.topAnchor.constraint(equalTo: userDataContainerView.bottomAnchor, constant: 12).isActive = true
        textViewsContainerView.bottomAnchor.constraint(equalTo: actionsContainerView.topAnchor, constant: 16).isActive = true
        textViewsContainerView.widthAnchor.constraint(equalTo: self.widthAnchor, constant: -32).isActive = true
        
        // needs x, y, h, w anchors
        postTextView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        postTextView.topAnchor.constraint(equalTo: textViewsContainerView.topAnchor, constant: 4).isActive = true
        postTextView.bottomAnchor.constraint(equalTo: resourceTextView.topAnchor, constant: -8).isActive = true
        postTextView.widthAnchor.constraint(equalTo: self.widthAnchor, constant: -32).isActive = true
        
        // needs x, y, h, w anchors
        resourceTextView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        resourceTextView.bottomAnchor.constraint(equalTo: textViewsContainerView.bottomAnchor, constant: -4).isActive = true
        resourceTextView.heightAnchor.constraint(equalTo: self.heightAnchor, multiplier: 1/8).isActive = true
        resourceTextView.widthAnchor.constraint(equalTo: self.widthAnchor, constant: -32).isActive = true
        
        // needs x, y, h, w anchors
        actionsContainerView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        actionsContainerView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
        actionsContainerView.heightAnchor.constraint(equalTo: self.heightAnchor, multiplier: 1/4).isActive = true
        actionsContainerView.widthAnchor.constraint(equalTo: self.widthAnchor).isActive = true
        
        // needs x, y, h, w anchors
        timestampLabel.leftAnchor.constraint(equalTo: actionsContainerView.leftAnchor, constant: 8).isActive = true
        timestampLabel.topAnchor.constraint(equalTo: likeButton.bottomAnchor, constant: 2).isActive = true
        timestampLabel.heightAnchor.constraint(equalTo: actionsContainerView.heightAnchor, multiplier: 1/3, constant: -8).isActive = true
        timestampLabel.widthAnchor.constraint(equalTo: actionsContainerView.widthAnchor, multiplier: 1/2).isActive = true
        
        // needs x, y, h, w anchors
        likeButton.leftAnchor.constraint(equalTo: actionsContainerView.leftAnchor, constant: 12).isActive = true
        likeButton.topAnchor.constraint(equalTo: actionsContainerView.topAnchor, constant: 16).isActive = true
        likeButton.heightAnchor.constraint(equalTo: actionsContainerView.heightAnchor, multiplier: 1/2, constant: -8).isActive = true
        likeButton.widthAnchor.constraint(equalTo: likeButton.heightAnchor).isActive = true
        
        // needs x, y, h, w anchors
        likesLabel.leftAnchor.constraint(equalTo: likeButton.rightAnchor, constant: 12).isActive = true
        likesLabel.centerYAnchor.constraint(equalTo: likeButton.centerYAnchor).isActive = true
        likesLabel.heightAnchor.constraint(equalTo: actionsContainerView.heightAnchor, multiplier: 1/2, constant: -8).isActive = true
        likesLabel.widthAnchor.constraint(equalTo: likesLabel.heightAnchor).isActive = true
        
        // needs x, y, h, w anchors
        commentsButton.leftAnchor.constraint(equalTo: likesLabel.rightAnchor, constant: -8).isActive = true
        commentsButton.centerYAnchor.constraint(equalTo: likeButton.centerYAnchor).isActive = true
        commentsButton.heightAnchor.constraint(equalTo: actionsContainerView.heightAnchor, multiplier: 1/2, constant: -8).isActive = true
        commentsButton.widthAnchor.constraint(equalTo: commentsButton.heightAnchor).isActive = true
        
        // needs x, y, h, w anchors
        bookmarkButton.leftAnchor.constraint(equalTo: commentsButton.rightAnchor, constant: 12).isActive = true
        bookmarkButton.centerYAnchor.constraint(equalTo: likeButton.centerYAnchor).isActive = true
        bookmarkButton.heightAnchor.constraint(equalTo: actionsContainerView.heightAnchor, multiplier: 1/2, constant: -8).isActive = true
        bookmarkButton.widthAnchor.constraint(equalTo: bookmarkButton.heightAnchor).isActive = true
        
    }
    
    func configCell(post: Post) {
        userImgView.loadImageUsingCacheWithUrlString(urlString: post.userImg!)
        completeNameLabel.text = post.userCompleteName
        usernameLabel.text = "@\(post.username!)"
        
        if let seconds = post.timestamp?.doubleValue {
            let timestampDate = Date(timeIntervalSince1970: seconds)
            let dateFormatter = DateFormatter()
            dateFormatter.dateFormat = "EEEE, MMM d, yyyy"
            self.timestampLabel.text = dateFormatter.string(from: timestampDate)
        }
        
        postTextView.text = post.postText
        resourceTextView.text = post.postResource
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

新闻负责人:

import UIKit
import Firebase
import FirebaseAuth
import FirebaseDatabase

class NewsViewController: UITableViewController {
    
    var activityIndicator = UIActivityIndicatorView(style: .large)
    var aiView = UIView()
    
    let cellId = "cellId"
    
    var posts = [Post]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setUpActivityIndicator()
        navigationItem.leftBarButtonItem = UIBarButtonItem(image: UIImage(systemName: "arrow.clockwise"), style: .plain, target: self, action: #selector(handleRefresh))
        navigationItem.rightBarButtonItem = UIBarButtonItem(image: UIImage(systemName: "square.and.pencil"), style: .done, target: self, action: #selector(didTapCreateButton))
        navigationItem.rightBarButtonItem?.tintColor = UIColor.mainColor
        navigationItem.leftBarButtonItem?.tintColor = UIColor.mainColor
        view.backgroundColor = .systemBackground
        title = "News"
        tableView.register(PostCell.self, forCellReuseIdentifier: cellId)
        
        startAI()
        observePosts()
    }
    
    func observePosts() {
        let ref = Database.database().reference().child("posts")
        
        ref.observe( .value, with: { (snapshot) in
            self.stopAI()
            if let snapshot = snapshot.children.allObjects as? [DataSnapshot] {
                
                self.posts.removeAll()
                
                for data in snapshot.reversed() {
                    
                    if let postDict = data.value as? [String: AnyObject] {
                        
                        let post = Post(dictionary: postDict, key: data.key)
                        self.posts.append(post)
                        
                    }
                    
                }
                
                self.tableView.reloadData()
                
            }
            
        }, withCancel: nil)
    }
    
    func setUpActivityIndicator() {
        aiView.layer.zPosition = 0.1
        aiView.backgroundColor = UIColor.gray
        aiView.alpha = 0
        aiView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(aiView)
        aiView.centerXAnchor.constraint(equalTo: tableView.centerXAnchor).isActive = true
        aiView.centerYAnchor.constraint(equalTo: tableView.centerYAnchor, constant: -60).isActive = true
        aiView.heightAnchor.constraint(equalToConstant: 150).isActive = true
        aiView.widthAnchor.constraint(equalToConstant: 150).isActive = true
        aiView.layer.masksToBounds = true
        aiView.layer.cornerRadius = 15
        
        activityIndicator.layer.zPosition = 0.2
        activityIndicator.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(activityIndicator)
        activityIndicator.centerXAnchor.constraint(equalTo: aiView.centerXAnchor).isActive = true
        activityIndicator.centerYAnchor.constraint(equalTo: aiView.centerYAnchor).isActive = true
    }
    
    func startAI() {
        activityIndicator.startAnimating()
        aiView.alpha = 0.80
        tableView.isUserInteractionEnabled = false
    }
    
    func stopAI() {
        self.activityIndicator.stopAnimating()
        self.tableView.isUserInteractionEnabled = true
        self.aiView.alpha = 0
    }
    
    @objc func handleRefresh() {
        startAI()
        observePosts()
        Alert.showAlert(vc: self, title: "Refreshed!", message: "News were refreshed successfully!")
    }
    
    @objc func didTapCreateButton() {
        let newPostVC = NewPostViewController()
        navigationController?.pushViewController(newPostVC, animated: true)
    }
    
    @objc func handleLike(_ sender: UIButton) {
        guard let uid = Auth.auth().currentUser?.uid else { return }
        let ref = Database.database().reference()
        guard let key = ref.child("posts").childByAutoId().key else { return }
        let selectedPost = posts[sender.tag]
        
        var hasLiked = false
        
        ref.child("users").child(uid).child("liked").queryOrderedByKey().observeSingleEvent(of: .value, with: { (snapshot) in
            
            guard let postId = selectedPost.postKey else { return }
            
            if let liked = snapshot.value as? [String: AnyObject] {
                
                for (ke, value) in liked {
                    
                    if value as? String == postId {
                        // User has liked post
                        hasLiked = true
                        
                        ref.child("users").child(uid).child("liked/\(ke)").removeValue()
                        ref.child("posts").child(postId).child("likes/\(ke)").removeValue()
                        
                        sender.likeButton()
                    }
                }
            }
            
            if !hasLiked {
                
                ref.child("users").child(uid).child("liked/\(key)").setValue(postId)
                ref.child("posts").child(postId).child("likes/\(key)").setValue(uid)
                
                sender.unlikeButton()
            }
            
        }, withCancel: nil)
        
        ref.removeAllObservers()
    }
    
    func checkLiked(row: Int, cell: PostCell) {
        guard let uid = Auth.auth().currentUser?.uid else { return }
        let ref = Database.database().reference()
        let selectedPost = posts[row]
        
        ref.child("users").child(uid).child("liked").queryOrderedByKey().observeSingleEvent(of: .value, with: { (snapshot) in
            
            guard let postId = selectedPost.postKey else { return }
            
            if let liked = snapshot.value as? [String: AnyObject] {
                
                for (_, value) in liked {
                    
                    if value as? String == postId {
                        
                        cell.likeButton.unlikeButton()
                        
                    }
                }
            }
        }, withCancel: nil)
        ref.removeAllObservers()
    }
    
    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 375
    }
    
    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 {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: cellId) as? PostCell else { return UITableViewCell() }
        checkLiked(row: indexPath.row, cell: cell)
        cell.likeButton.tag = indexPath.row
        cell.likeButton.addTarget(self, action: #selector(handleLike(_:)), for: .touchUpInside)
        cell.configCell(post: posts[indexPath.row])
        return cell
    }
    
}

extension UIButton {
    
    func likeButton() {
        self.setImage(UIImage(systemName: "hand.thumbsup"), for: .normal)
        self.tintColor = UIColor.mainColor
    }
    
    func unlikeButton() {
        self.setImage(UIImage(systemName: "hand.thumbsup.fill"), for: .normal)
        self.tintColor = UIColor.mainColor
    }
}

这里我给点赞按钮添加目标:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: cellId) as? PostCell else { return UITableViewCell() }
        checkLiked(row: indexPath.row, cell: cell)
        cell.likeButton.tag = indexPath.row
        cell.likeButton.addTarget(self, action: #selector(handleLike(_:)), for: .touchUpInside)
        cell.configCell(post: posts[indexPath.row])
        return cell
}

我找到了解决方法,问题是视图需要添加到 contentView 而不是 PostCell

代码如下:

import UIKit

class PostCell: UITableViewCell {
    
    let userDataContainerView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()
    
    let userImgView: UIImageView = {
        let iv = UIImageView()
        iv.translatesAutoresizingMaskIntoConstraints = false
        iv.image = UIImage(named: "person.crop.circle.fill")?.maskWithColor(color: UIColor.mainColor)
        return iv
    }()
    
    let completeNameLabel: UILabel = {
        let lbl = UILabel()
        lbl.translatesAutoresizingMaskIntoConstraints = false
        lbl.font = UIFont.systemFont(ofSize: 18, weight: .semibold)
        lbl.textColor = UIColor.darkText
        lbl.adjustsFontSizeToFitWidth = true
        return lbl
    }()
    
    let usernameLabel: UILabel = {
        let lbl = UILabel()
        lbl.translatesAutoresizingMaskIntoConstraints = false
        lbl.font = UIFont.systemFont(ofSize: 16, weight: .medium)
        lbl.textColor = UIColor.darkGray
        lbl.adjustsFontSizeToFitWidth = true
        return lbl
    }()
    
    let timestampLabel: UILabel = {
        let lbl = UILabel()
        lbl.translatesAutoresizingMaskIntoConstraints = false
        lbl.font = UIFont.systemFont(ofSize: 14, weight: .regular)
        lbl.textColor = UIColor.gray
        lbl.adjustsFontSizeToFitWidth = true
        return lbl
    }()
    
    let moreOptionsButton: UIButton = {
        let button = UIButton()
        button.translatesAutoresizingMaskIntoConstraints = false
        button.setImage(UIImage(systemName: "ellipsis"), for: .normal)
        button.tintColor = UIColor.mainColor
        button.contentVerticalAlignment = .fill
        button.contentHorizontalAlignment = .fill
        return button
    }()
    
    let textViewsContainerView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()
    
    let textViewSeparatorView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.backgroundColor = UIColor.black
        return view
    }()
    
    let postTextView: UITextView = {
        let tv = UITextView()
        tv.translatesAutoresizingMaskIntoConstraints = false
        tv.isEditable = false
        tv.font = UIFont.systemFont(ofSize: 22, weight: .medium)
        tv.adjustsFontForContentSizeCategory = true
        tv.layer.masksToBounds = true
        tv.layer.cornerRadius = 16
        tv.layer.borderWidth = 0.5
        tv.layer.borderColor = CGColor.mainColor
        return tv
    }()
    
    let resourceTextView: UITextView = {
        let tv = UITextView()
        tv.translatesAutoresizingMaskIntoConstraints = false
        tv.isEditable = false
        tv.font = UIFont.systemFont(ofSize: 18, weight: .medium)
        tv.adjustsFontForContentSizeCategory = true
        tv.layer.masksToBounds = true
        tv.layer.cornerRadius = 16
        tv.layer.borderWidth = 0.5
        tv.layer.borderColor = CGColor.mainColor
        tv.isSelectable = true
        return tv
    }()
    
    let actionsContainerView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()
    
    let likeButton: UIButton = {
        let button = UIButton()
        button.isUserInteractionEnabled = true
        button.translatesAutoresizingMaskIntoConstraints = false
        button.setImage(UIImage(systemName: "hand.thumbsup"), for: .normal)
        button.tintColor = UIColor.mainColor
        button.contentVerticalAlignment = .fill
        button.contentHorizontalAlignment = .fill
        button.imageEdgeInsets = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
        return button
    }()
    
    let likesLabel: UILabel = {
        let lbl = UILabel()
        lbl.translatesAutoresizingMaskIntoConstraints = false
        lbl.text = "0"
        lbl.textColor = UIColor.mainColor
        lbl.font = UIFont.systemFont(ofSize: 16, weight: .medium)
        lbl.adjustsFontSizeToFitWidth = true
        return lbl
    }()
    
    let commentsButton: UIButton = {
        let button = UIButton()
        button.translatesAutoresizingMaskIntoConstraints = false
        button.setImage(UIImage(systemName: "bubble.left"), for: .normal)
        button.tintColor = UIColor.mainColor
        button.contentVerticalAlignment = .fill
        button.contentHorizontalAlignment = .fill
        button.imageEdgeInsets = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
        return button
    }()

    let bookmarkButton: UIButton = {
        let button = UIButton()
        button.translatesAutoresizingMaskIntoConstraints = false
        button.setImage(UIImage(systemName: "bookmark"), for: .normal)
        button.tintColor = UIColor.mainColor
        button.contentVerticalAlignment = .fill
        button.contentHorizontalAlignment = .fill
        button.imageEdgeInsets = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
        return button
    }()
    
    override func layoutSubviews() {
        super.layoutSubviews()
        userImgView.circleImageView()
    }
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: .default, reuseIdentifier: reuseIdentifier)
        self.selectionStyle = .none
        contentView.addSubview(userDataContainerView)
        userDataContainerView.addSubview(userImgView)
        userDataContainerView.addSubview(completeNameLabel)
        userDataContainerView.addSubview(usernameLabel)
        userDataContainerView.addSubview(moreOptionsButton)
        contentView.addSubview(textViewsContainerView)
        contentView.addSubview(textViewSeparatorView)
        textViewsContainerView.addSubview(postTextView)
        textViewsContainerView.addSubview(resourceTextView)
        contentView.addSubview(actionsContainerView)
        actionsContainerView.addSubview(likeButton)
        actionsContainerView.addSubview(likesLabel)
        actionsContainerView.addSubview(commentsButton)
        actionsContainerView.addSubview(bookmarkButton)
        actionsContainerView.addSubview(timestampLabel)
        setUpConstraints()
    }
    
    func setUpConstraints() {
        // needs x, y, h, w anchors
        userDataContainerView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        userDataContainerView.topAnchor.constraint(equalTo: self.topAnchor, constant: 8).isActive = true
        userDataContainerView.heightAnchor.constraint(equalTo: self.heightAnchor, multiplier: 1/5).isActive = true
        userDataContainerView.widthAnchor.constraint(equalTo: self.widthAnchor).isActive = true
        
        // needs x, y, h, w anchors
        userImgView.leftAnchor.constraint(equalTo: userDataContainerView.leftAnchor, constant: 8).isActive = true
        userImgView.topAnchor.constraint(equalTo: userDataContainerView.topAnchor, constant: 8).isActive = true
        userImgView.heightAnchor.constraint(equalTo: userDataContainerView.heightAnchor, constant: -16).isActive = true
        userImgView.widthAnchor.constraint(equalTo: userImgView.heightAnchor).isActive = true
        
        // needs x, y, h, w anchors
        completeNameLabel.leftAnchor.constraint(equalTo: userImgView.rightAnchor, constant: 8).isActive = true
        completeNameLabel.topAnchor.constraint(equalTo: userDataContainerView.topAnchor, constant: 4).isActive = true
        completeNameLabel.heightAnchor.constraint(equalTo: userDataContainerView.heightAnchor, multiplier: 1/2, constant: -8).isActive = true
        completeNameLabel.widthAnchor.constraint(equalTo: userDataContainerView.widthAnchor, multiplier: 1/2).isActive = true
        
        // needs x, y, h, w anchors
        usernameLabel.leftAnchor.constraint(equalTo: userImgView.rightAnchor, constant: 8).isActive = true
        usernameLabel.topAnchor.constraint(equalTo: completeNameLabel.bottomAnchor, constant: 4).isActive = true
        usernameLabel.heightAnchor.constraint(equalTo: userDataContainerView.heightAnchor, multiplier: 1/2, constant: -8).isActive = true
        usernameLabel.widthAnchor.constraint(equalTo: userDataContainerView.widthAnchor, multiplier: 1/2).isActive = true
        
        // needs x, y, w, anchors
        moreOptionsButton.rightAnchor.constraint(equalTo: userDataContainerView.rightAnchor, constant: -16).isActive = true
        moreOptionsButton.topAnchor.constraint(equalTo: userDataContainerView.topAnchor, constant: 16).isActive = true
        moreOptionsButton.heightAnchor.constraint(equalTo: userImgView.heightAnchor, multiplier: 1/4, constant: -4).isActive = true
        moreOptionsButton.widthAnchor.constraint(equalTo: userImgView.heightAnchor, multiplier: 2/3).isActive = true
        
        // needs x, y, h, w anchors
        textViewSeparatorView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        textViewSeparatorView.bottomAnchor.constraint(equalTo: userDataContainerView.bottomAnchor).isActive = true
        textViewSeparatorView.heightAnchor.constraint(equalToConstant: 0.5).isActive = true
        textViewSeparatorView.widthAnchor.constraint(equalTo: self.widthAnchor).isActive = true
        
        // needs x, y, h, w anchors
        textViewsContainerView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        textViewsContainerView.topAnchor.constraint(equalTo: userDataContainerView.bottomAnchor, constant: 12).isActive = true
        textViewsContainerView.bottomAnchor.constraint(equalTo: actionsContainerView.topAnchor, constant: 16).isActive = true
        textViewsContainerView.widthAnchor.constraint(equalTo: self.widthAnchor, constant: -32).isActive = true
        
        // needs x, y, h, w anchors
        postTextView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        postTextView.topAnchor.constraint(equalTo: textViewsContainerView.topAnchor, constant: 4).isActive = true
        postTextView.bottomAnchor.constraint(equalTo: resourceTextView.topAnchor, constant: -8).isActive = true
        postTextView.widthAnchor.constraint(equalTo: self.widthAnchor, constant: -32).isActive = true
        
        // needs x, y, h, w anchors
        resourceTextView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        resourceTextView.bottomAnchor.constraint(equalTo: textViewsContainerView.bottomAnchor, constant: -4).isActive = true
        resourceTextView.heightAnchor.constraint(equalTo: self.heightAnchor, multiplier: 1/8).isActive = true
        resourceTextView.widthAnchor.constraint(equalTo: self.widthAnchor, constant: -32).isActive = true
        
        // needs x, y, h, w anchors
        actionsContainerView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        actionsContainerView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
        actionsContainerView.heightAnchor.constraint(equalTo: self.heightAnchor, multiplier: 1/4).isActive = true
        actionsContainerView.widthAnchor.constraint(equalTo: self.widthAnchor).isActive = true
        
        // needs x, y, h, w anchors
        timestampLabel.leftAnchor.constraint(equalTo: actionsContainerView.leftAnchor, constant: 8).isActive = true
        timestampLabel.topAnchor.constraint(equalTo: likeButton.bottomAnchor, constant: 2).isActive = true
        timestampLabel.heightAnchor.constraint(equalTo: actionsContainerView.heightAnchor, multiplier: 1/3, constant: -8).isActive = true
        timestampLabel.widthAnchor.constraint(equalTo: actionsContainerView.widthAnchor, multiplier: 1/2).isActive = true
        
        // needs x, y, h, w anchors
        likeButton.leftAnchor.constraint(equalTo: actionsContainerView.leftAnchor, constant: 12).isActive = true
        likeButton.topAnchor.constraint(equalTo: actionsContainerView.topAnchor, constant: 16).isActive = true
        likeButton.heightAnchor.constraint(equalTo: actionsContainerView.heightAnchor, multiplier: 1/2, constant: -8).isActive = true
        likeButton.widthAnchor.constraint(equalTo: likeButton.heightAnchor).isActive = true
        
        // needs x, y, h, w anchors
        likesLabel.leftAnchor.constraint(equalTo: likeButton.rightAnchor, constant: 12).isActive = true
        likesLabel.centerYAnchor.constraint(equalTo: likeButton.centerYAnchor).isActive = true
        likesLabel.heightAnchor.constraint(equalTo: actionsContainerView.heightAnchor, multiplier: 1/2, constant: -8).isActive = true
        likesLabel.widthAnchor.constraint(equalTo: likesLabel.heightAnchor).isActive = true
        
        // needs x, y, h, w anchors
        commentsButton.leftAnchor.constraint(equalTo: likesLabel.rightAnchor, constant: -8).isActive = true
        commentsButton.centerYAnchor.constraint(equalTo: likeButton.centerYAnchor).isActive = true
        commentsButton.heightAnchor.constraint(equalTo: actionsContainerView.heightAnchor, multiplier: 1/2, constant: -8).isActive = true
        commentsButton.widthAnchor.constraint(equalTo: commentsButton.heightAnchor).isActive = true
        
        // needs x, y, h, w anchors
        bookmarkButton.leftAnchor.constraint(equalTo: commentsButton.rightAnchor, constant: 12).isActive = true
        bookmarkButton.centerYAnchor.constraint(equalTo: likeButton.centerYAnchor).isActive = true
        bookmarkButton.heightAnchor.constraint(equalTo: actionsContainerView.heightAnchor, multiplier: 1/2, constant: -8).isActive = true
        bookmarkButton.widthAnchor.constraint(equalTo: bookmarkButton.heightAnchor).isActive = true
        
    }
    
    func configCell(post: Post) {
        userImgView.loadImageUsingCacheWithUrlString(urlString: post.userImg!)
        completeNameLabel.text = post.userCompleteName
        usernameLabel.text = "@\(post.username!)"
        
        if let seconds = post.timestamp?.doubleValue {
            let timestampDate = Date(timeIntervalSince1970: seconds)
            let dateFormatter = DateFormatter()
            dateFormatter.dateFormat = "EEEE, MMM d, yyyy"
            self.timestampLabel.text = dateFormatter.string(from: timestampDate)
        }
        
        postTextView.text = post.postText
        resourceTextView.text = post.postResource
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}