Search code examples
swiftuicollectionviewuikituicollectionviewcell

Button in custom UICollectionViewCell class does not taking action


Hi I am developing a route finder application, and inside the application when user searches for specific places, app provides number of places on both map and in UICollectionView which contains short description of list of places found and a "Go" UIButton to show the direction. However, despite the fact that button is shown on the cell and is touchable, meaning isUserInteractionEnabled is true, button is not triggering an action. "Pressed" is not shown on console. (Note: Screen shot is available for demonstration purposes.)

Declaration of the UICollectionView in MapViewController.

let collectionViewOfListOfPlaces:UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
        cv.translatesAutoresizingMaskIntoConstraints = false
        cv.register(CustomCell.self, forCellWithReuseIdentifier: "cell")
        return cv
    }()

In viewDidLoad function of MapViewController this lines are added.

collectionViewOfListOfPlaces.reloadData()
collectionViewOfListOfPlaces.delegate = self

In extension of MapViewController this lines functions are added.

func setupCollectionViewOfListOfPlaces(){
        hideListViewButton.translatesAutoresizingMaskIntoConstraints = false
        hideListViewButton.isUserInteractionEnabled = true
        collectionViewOfListOfPlaces.backgroundColor = UIColor.white.withAlphaComponent(0)
        collectionViewOfListOfPlaces.topAnchor.constraint(equalTo: listContentView.topAnchor, constant: 0).isActive = true
        collectionViewOfListOfPlaces.leadingAnchor.constraint(equalTo: listContentView.leadingAnchor, constant: 10).isActive = true
        collectionViewOfListOfPlaces.trailingAnchor.constraint(equalTo: listContentView.trailingAnchor, constant: -10).isActive = true
        collectionViewOfListOfPlaces.heightAnchor.constraint(equalToConstant: view.frame.height/5).isActive = true  // ?
    }
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: collectionViewOfListOfPlaces.frame.height/0.8, height: collectionViewOfListOfPlaces.frame.height/1.2)
    }
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return landmarks.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionViewOfListOfPlaces.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CustomCell
        let cellData = self.landmarks[indexPath.item]
        cell.backgroundColor = Colors.violet3
        cell.setData(dataa: cellData) //????????
        cell.delegate = self
        return cell
    }

Custom class:

import Foundation
import UIKit

protocol CustomCellDelegate {
    func didPrintNameOfPlace(placeName: String)
}

class CustomCell: UICollectionViewCell {
    
//    var data: Landmark? {
//        didSet {
//            guard let data = data else { return }
//
//        }
//    }
    let directButton: UIButton = {
        let button = UIButton(type: .system)
        button.setTitle("Go", for: .normal)
        button.titleLabel?.font = .systemFont(ofSize: 18)
        button.addTarget(
            self,
            action: #selector(directButtonPressed),
            for: UIControl.Event.touchUpInside)
        button.backgroundColor = .white
        return button
    }()
    
    var data: Landmark?
    var delegate: CustomCellDelegate?
    
    override init(frame: CGRect) {
        super.init(frame: .zero)
        
        setUpDirectButton()
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    func setData(dataa: Landmark){
        data = dataa
        
    }
    
    func setUpDirectButton(){
        contentView.addSubview(directButton)
        directButton.translatesAutoresizingMaskIntoConstraints = false
        directButton.isUserInteractionEnabled = true
        directButton.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 0).isActive = true
        directButton.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant:  0).isActive = true
        directButton.widthAnchor.constraint(equalToConstant: 50).isActive = true
        directButton.heightAnchor.constraint(equalToConstant: 50).isActive = true
        directButton.frame.size.width = 50
        directButton.frame.size.height = 50
    }
    
    @objc func directButtonPressed(sender: UIButton!) {
//        delegate?.didPrintNameOfPlace(placeName: data!.nameOfPlace)
        print("Pressed")
        
    }
}
```[Screen shot link][1]


  [1]: https://i.sstatic.net/azHSd.jpg

Solution

  • Mark your button initialise with lazy

    private lazy var directButton: UIButton = {
            let button = UIButton(type: .system)
            button.setTitle("Go", for: .normal)
            button.titleLabel?.font = .systemFont(ofSize: 18)
            button.addTarget(
                self,
                action: #selector(directButtonPressed),
                for: UIControl.Event.touchUpInside)
            button.backgroundColor = .white
            return button
        }()