Search code examples
iosswiftuitapgesturerecognizer

Accessing subviews from UITapGestureRecognizer


I have a collection view with cells that are populated based on an array. Each cell has a UIImageView and an UILabel. I want to be able to update the text within the UILabel each time the Cell View itself is tapped. I have the tapping gesture working fine and i can print out the sender information and access the sender view and even get the restoration identifier but I can't seem to access the 'myImage' or 'myLabel' sub views within that cell which is being tapped.

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

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath as IndexPath) as! CardCell

    cell.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(tap)))

    let railroadName = railroadNames[indexPath.item]
    cell.myImage.image = #imageLiteral(resourceName:railroadName)
    cell.myImage.clipsToBounds = true
    cell.myImage.layer.cornerRadius = 8
    cell.restorationIdentifier = railroadName

    cell.myLabel.isHidden = true
    cell.myLabel.text = "2"
    cell.myLabel.layer.backgroundColor = UIColor(red:0.25, green:0.52, blue:0.96, alpha:1.0).cgColor
    cell.myLabel.layer.cornerRadius = 18
    cell.myLabel.textColor = UIColor.white

    return cell
}

@objc func tap(_ sender: UITapGestureRecognizer) {
    //print(sender)
    //print(sender.view?.restorationIdentifier)
}

Can't access subviews. Want to take the current text from 'myLabel' and increase the count by 1 each tap.


Solution

  • You can use below code to get label text of cell. but i insist you to manage this in railroadNames array. so, you can save label text in array object's field and can get that field value using indexpath using below code and perform operation on based of your requirement. and then you can reload that particular cell to show effect on tableview.

    Also, you should use didSelectItemAt method to get select cell event. if not necessary reason to use UITapGestureRecognizer.

    @objc func tap(_ sender: UITapGestureRecognizer) {
    
        //Get Collection view cell indexpath on based of location of tap gesture
        let cellPosition = sender.location(in: self.collectionView)
        guard let indexPath = self.collectionView.indexPathForItem(at: cellPosition) else{
            print("Indexpath not found")
            return
        }
    
        //Get Ceollection view cell
        guard let cell = self.collectionView.cellForItem(at: indexPath) as? CellMainCategoryList else{
            print("Could't found cell")
            return
        }
    
        //Get String of label of collection view cell
        let strMyLable = cell. myLabel.text
        //you can process addition on based of your requirement here by getting Int from above string.
    }
    

    instead of above, you can manage it like below code also:

    @objc func tap(_ sender: UITapGestureRecognizer) {
    
        let cellPosition = sender.location(in: self.collectionViewCategaries)
        guard let indexPath = self.collectionViewCategaries.indexPathForItem(at: cellPosition) else{
            print("Indexpath not found")
            return
        }
        let railroadName = railroadNames[indexPath.item]
        let myLableText = railroadName.myLabelValue
        //update value
        railroadName.myLabelValue = "2"
    
        self.collectionView.reloadItems(at: [indexPath])
    }
    

    Hope this helps.