Swift: Action button inside a collectionviewcell

寵の児 提交于 2020-01-06 17:58:25

问题


I have a button inside a collectionview cell that I programmatically created.

  @IBAction func editButtonTapped() -> Void {
        print("Hello Edit Button")

    }

j

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

 let editButton = UIButton(frame: CGRect(x: 8, y: 241, width: 154, height: 37))
            editButton.setImage(UIImage(named: "background-1 (dragged).tiff"), for: UIControlState.normal)
            editButton.addTarget(self, action: #selector(editButtonTapped), for: UIControlEvents.touchUpInside)
            editButton.tag = indexPath.row
            editButton.isUserInteractionEnabled = true

            cell.addSubview(editButton)
            cell.bringSubview(toFront: editButton)
}

But when I click on the button, nothing happens (it doesn't show "Hello Edit Button"). What am I missing


回答1:


There are a few things you should do differently, but this works fine for me (pretty much just the code you posted):

class TestCollWithBtnsCollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {

    @IBAction func editButtonTapped() -> Void {
        print("Hello Edit Button")
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
    {
        return CGSize(width: 200.0, height: 200.0)
    }

    override func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }

    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 8
    }

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)

        cell.backgroundColor = .orange

        // this is the WRONG way to do this...
        //  1) the button is being added avery time a cell is reused
        //  2) the button should be added to the cell.contentView (not the cell itself)
        //  3) much better ways to track than setting the button .tag to the row
        //  4) target for the button action is "self" - locks you into a bad structure
        // however, this can help us debug the problem

        let editButton = UIButton(frame: CGRect(x: 8, y: 41, width: 154, height: 37))

        // I don't have an image, so I set a button title and background color
        editButton.setTitle("\(indexPath.row)", for: .normal)
        editButton.backgroundColor = .red
//      editButton.setImage(UIImage(named: "background-1 (dragged).tiff"), for: UIControlState.normal)

        editButton.addTarget(self, action: #selector(editButtonTapped), for: UIControlEvents.touchUpInside)
        editButton.tag = indexPath.row
        editButton.isUserInteractionEnabled = true

        cell.addSubview(editButton)

        return cell
    }

}

If you can see your button in your collection view cells, then your code (assuming you have the cell being created correctly) should have worked.

The fact that you also have the line:

cell.bringSubview(toFront: editButton)

kinda makes me think you don't see the button... Possibly your Y coordinate of 241 places it outside the cell frame?




回答2:


What's happening is the collection view is capturing the touch events and processing them. You need to specify that the collection view needs to pass the touch event to its subclasses.

override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {

    //loop through the cells, get each cell, and run this test on each cell
    //you need to define a proper loop
    for cell in cells {

         //if the touch was in the cell
         if cell.frame.contains(point) {
            //get the cells button
            for uiview in cell.subviews {
                if uiview is UIButton {
                   let button = uiview as! UIButton
                   //if the button received the touch, return it, if not, return the cell
                    if button.frame.contains(point) {
                       return button
                    }
                    else {
                       return cell
                    }
                 }
             }
         }
    }
    //after the loop, if it could not find the touch in one of the cells return the view you are on
    return view

}


来源:https://stackoverflow.com/questions/43766963/swift-action-button-inside-a-collectionviewcell

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