Swift - UIButton in UICollectionViewCell not clickable

十年热恋 提交于 2019-12-24 09:24:21

问题


I currently have a UICollectionViewController to display all my news articles. For my news items, I have created a custom UICollectionViewCell with a small button in the top right corner.

The problem is that it is only working when I set my feedCell to isUserInteractionEnabled = true. I only want the newsMenu button to be clickable, not have the whole cell to be selectable.

How do I achieve this?

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    let feedCell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! FeedCell

    feedCell.post = m_Collection?[(indexPath as NSIndexPath).item]

    feedCell.newsMenu.addTarget(self, action: #selector(imageTapped), for: .touchUpInside)

    return feedCell
}

func imageTapped(button: UIButton)
{
    let newsAction = UIAlertController(title: "Message", message: "Do you want to edit or delete this news message?", preferredStyle: .actionSheet)

    let editAction = UIAlertAction(title: "Edit news", style: .default, handler: menuEditNews)
    let deleteAction = UIAlertAction(title: "Delete news", style: .destructive, handler: menuDeleteNews)
    let cancelAction = UIAlertAction(title: "Cancel", style: .cancel)

    newsAction.addAction(editAction)
    newsAction.addAction(deleteAction)
    newsAction.addAction(cancelAction)

    self.present(newsAction, animated: true, completion: nil)
}

My custom cell:

class FeedCell: UICollectionViewCell {

override init(frame: CGRect) {
    super.init(frame: frame)

    setupViews()
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

let titleLabel: UILabel = {
    let label = UILabel()
    label.adjustsFontSizeToFitWidth = false
    label.lineBreakMode = .byTruncatingTail
    label.numberOfLines = 2
    return label
}()

let profileImageView: UIImageView = {
    let imageView = UIImageView()
    imageView.translatesAutoresizingMaskIntoConstraints = false
    imageView.image = UIImage(named: "")
    imageView.layer.cornerRadius = 22
    imageView.layer.masksToBounds = true
    return imageView
}()

let newsTextView: UITextView = {
    let textView = UITextView()
    textView.isScrollEnabled = false
    textView.font = UIFont (name: "Helvetica", size: 13)
    return textView
}()

let newsMenu: UIButton = {
    let newsMenu = UIButton()
    newsMenu.isUserInteractionEnabled = true
    newsMenu.setImage(UIImage(named: "news_menuitem"), for: UIControlState())
    return newsMenu
}()

func setupViews() {
    backgroundColor = UIColor.white

    addSubview(titleLabel)
    addSubview(profileImageView)
    addSubview(newsTextView)
    addSubview(newsMenu)

    addConstraintsWithFormat("H:|-8-[v0(44)]-8-[v1]-10-[v2(25)]-8-|", views: profileImageView, titleLabel, newsMenu)
    addConstraintsWithFormat("H:|-4-[v0]-4-|", views: newsTextView)
    addConstraintsWithFormat("V:|-6-[v0]", views: newsMenu)
    addConstraintsWithFormat("V:|-10-[v0]", views: titleLabel)
    addConstraintsWithFormat("V:|-8-[v0(44)]-4-[v1]", views: profileImageView, newsTextView)
}
}

回答1:


The reason why the keyboard appears when tapping the cell is most likely that you're in fact tapping on the UITextView, to prevent this behavior just set the isUserInteractionEnabled flag to false on the newsTextView object.




回答2:


Change your code to:

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        let feedCell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! FeedCell

        feedCell.post = m_Collection?[(indexPath as NSIndexPath).item]

        feedCell.sourceController = self // assign controller

        return feedCell
    }

    func imageTapped() // remove (button: UIButton)
    {
        let newsAction = UIAlertController(title: "Message", message: "Do you want to edit or delete this news message?", preferredStyle: .actionSheet)

        let editAction = UIAlertAction(title: "Edit news", style: .default, handler: menuEditNews)
        let deleteAction = UIAlertAction(title: "Delete news", style: .destructive, handler: menuDeleteNews)
        let cancelAction = UIAlertAction(title: "Cancel", style: .cancel)

        newsAction.addAction(editAction)
        newsAction.addAction(deleteAction)
        newsAction.addAction(cancelAction)

        self.present(newsAction, animated: true, completion: nil)
    }

And your custom cell:

class FeedCell: UICollectionViewCell {

    override init(frame: CGRect) {
        super.init(frame: frame)

        setupViews()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    weak var sourceController: YourController?  // declare new variable

    let titleLabel: UILabel = {
        let label = UILabel()
        label.adjustsFontSizeToFitWidth = false
        label.lineBreakMode = .byTruncatingTail
        label.numberOfLines = 2
        return label
    }()

    let profileImageView: UIImageView = {
        let imageView = UIImageView()
        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageView.image = UIImage(named: "")
        imageView.layer.cornerRadius = 22
        imageView.layer.masksToBounds = true
        return imageView
    }()

    let newsTextView: UITextView = {
        let textView = UITextView()
        textView.isScrollEnabled = false
        textView.font = UIFont (name: "Helvetica", size: 13)
        return textView
    }()

    lazy var newsMenu: UIButton = {  // change `let` to `lazy var`
        let newsMenu = UIButton()
        newsMenu.isUserInteractionEnabled = true
        newsMenu.setImage(UIImage(named: "news_menuitem"), for: UIControlState())
        newsMenu.addTarget(self, action: #selector(actionTap), for: .touchUpInside) // add target to button
        return newsMenu
    }()

    func setupViews() {
        backgroundColor = UIColor.white

        addSubview(titleLabel)
        addSubview(profileImageView)
        addSubview(newsTextView)
        addSubview(newsMenu)

        addConstraintsWithFormat("H:|-8-[v0(44)]-8-[v1]-10-[v2(25)]-8-|", views: profileImageView, titleLabel, newsMenu)
        addConstraintsWithFormat("H:|-4-[v0]-4-|", views: newsTextView)
        addConstraintsWithFormat("V:|-6-[v0]", views: newsMenu)
        addConstraintsWithFormat("V:|-10-[v0]", views: titleLabel)
        addConstraintsWithFormat("V:|-8-[v0(44)]-4-[v1]", views: profileImageView, newsTextView)
    }

    func actionTap() {  // handle function
         sourceController?. imageTapped()
    }


}



回答3:


imageTapped have param, so you must addtarget:

feedCell.newsMenu.addTarget(self, action: #selector(imageTapped(_:)), for: .touchUpInside)


来源:https://stackoverflow.com/questions/42504935/swift-uibutton-in-uicollectionviewcell-not-clickable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!