Swift 3- How to get button in UICollectionViewCell work

前端 未结 6 740
夕颜
夕颜 2020-12-09 23:19

I am trying to implement an Edit button inside a cell.

Please refer to image:

What I done so far:

MainController:

class MainCo         


        
相关标签:
6条回答
  • 2020-12-09 23:51

    If touch action on UIButton is not detecting.

    To enable touch action on the UIButton of your Custom UICollectionCell, add the below method in your Custom UICollectionCell class.

    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        var view = myButton.hitTest(myButton.convert(point, from: self), with: event)
        if view == nil {
            view = super.hitTest(point, with: event)
        }
    
        return view
    }
    
    0 讨论(0)
  • 2020-12-09 23:54

    You might want to use a tag for a simpler approach, but I always implement a delegate pattern in the case of buttons inside cells

    protocol MyCollectionViewCellDelegate: class {
        func button(wasPressedOnCell cell: MyCollectionViewCell)
    }
    class MyCollectionViewCell: UICollectionViewCell {
        weak var delegate: MyCollectionViewCellDelegate?
        var data: String = "DATA"
        @IBAction func buttonWasPressed(sender: UIButton){
            delegate?.button(wasPressedOnCell: self)
        }
    
    }
    class MainViewController: UIViewController, UICollectionViewDataSource {
        func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "reuse", for: indexPath) as! MyCollectionViewCell
            cell.delegate = self
            return cell
        }
    }
    extension MainViewController: MyCollectionViewCellDelegate{
        func button(wasPressedOnCell cell: MyCollectionViewCell) {
            //do what you want with the cell and data
        }
    }
    

    Using this method will allow you to have multiple buttons inside a cell. Use a different delegate method for each button

    0 讨论(0)
  • 2020-12-10 00:04

    A very reliable and flexible pattern is to assign a "Callback Closure" to your cell. Put your button action handler inside the cell, and have it "call back" to the view controller.

    Here is a basic example (you should be able to implement it with your custom cell with no problem):

    //
    //  CViewWithButtonCollectionViewController.swift
    //  SWTemp2
    //
    //  Created by Don Mag on 6/5/17.
    //  Copyright © 2017 DonMag. All rights reserved.
    //
    
    import UIKit
    
    private let reuseIdentifier = "ImgItemCell"
    
    class ImgItemCell: UICollectionViewCell {
    
        // this will be our "call back" action
        var btnTapAction : (()->())?
    
        override init(frame: CGRect){
            super.init(frame: frame)
            setupViews()
        }
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
            setupViews()
        }
    
        let editButton: UIButton = {
            let button = UIButton(type: UIButtonType.system)
            button.translatesAutoresizingMaskIntoConstraints = false
            button.backgroundColor = .white
            button.setTitle("Edit", for: .normal)
            return button
        }()
    
        func setupViews(){
    
            // add a button
            addSubview(editButton)
    
            editButton.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
            editButton.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
    
            // add the touchUpInside target
            editButton.addTarget(self, action: #selector(btnTapped), for: .touchUpInside)
    
        }
    
        @objc func btnTapped() {
            print("Tapped!")
    
            // use our "call back" action to tell the controller the button was tapped
            btnTapAction?()
        }
    
    }
    
    class CViewWithButtonCollectionViewController: UICollectionViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            if let layout = collectionView?.collectionViewLayout as? UICollectionViewFlowLayout {
                layout.itemSize = CGSize(width: 300, height: 100)
            }
    
        }
    
        override func numberOfSections(in collectionView: UICollectionView) -> Int {
            return 1
        }
        override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
            return 10
        }
    
        override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! ImgItemCell
    
            cell.backgroundColor = .red
    
            // set a "Callback Closure" in the cell
            cell.btnTapAction = {
                () in
                print("Edit tapped in cell", indexPath)
                // start your edit process here...
            }
    
            return cell
        }
    
    }
    
    0 讨论(0)
  • 2020-12-10 00:07

    How your buttonpress method will know,you are selecting which cell button.So you can differentiate with tag
    Add in cellForItemAtindexPath

    ButtonObject.tag = indexPath.item
    

    and

    func buttonPressed(_ sender: UIButton)
        {
            print("buttonPressed ! \(sender.tag)")
        }
    
    0 讨论(0)
  • 2020-12-10 00:12
    func setupViews() {
        ...
        addSubview(editButton)
        editButton.addTarget(self, action: #selector(buttonPressed), for: .touchUpInside)
    }
    
    func buttonPressed(sender:UIButton){
        print("buttonPressed !")
    }
    
    0 讨论(0)
  • 2020-12-10 00:13

    I have created the same scenario. The only difference is that I have used UIButton instead of RaisedButton. And it is working perfectly fine.

    1.ImgItemCell

    class ImgItemCell: UICollectionViewCell
    {
        //MARK: View Lifecycle Methods
        override func awakeFromNib()
        {
            super.awakeFromNib()
            setupViews()
        }
    
        let editButton: UIButton = {
            let button = UIButton(frame: CGRect(x: 0, y: 0, width: 30, height: 50))
            button.setTitle("Edit", for: .normal)
            return button
        }()
    
        func setupViews()
        {
            addSubview(editButton)
        }
    }
    

    2.MainController methods

    //MARK: UICollectionViewDataSource
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
    {
        return 10
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
    {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: imgCellId, for: indexPath) as! ImgItemCell
        cell.editButton.addTarget(self, action: #selector(buttonPressed), for: .touchUpInside)
        return cell
    }
    
    @objc func buttonPressed()
    {
        print("buttonPressed !")
    }
    
    0 讨论(0)
提交回复
热议问题