My UIView is not responding to the UITapGestureRecognizer

39 Views Asked by At

I have a selector for UIView, which has to trigger when the UIView is touched but when I click on the UIView there is no action at all even if it is not responding to the breaking point. My other UIViews work perfectly fine. Here's the code to look at:

 class DetailVC: UIViewController {
        let firstTypeView = CustomView()
        let secondTypeView = CustomView()
        let thirdTypeView = CustomView()
    
        override func viewDidAppear(_ animated: Bool) {
            super.viewDidAppear(animated)
            addTapGestureToViews()
    
        } 

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

        firstTypeView.setBoiledType()
    firstTypeView.imageView.image = UIImage(named: "Soft egg png")
    firstTypeView.setFrame(x: 38, y: boiledTypeLbl.frame.maxY + 40, width: 91, height: 128)
    firstTypeView.setLbl(x: firstTypeView.frame.width/2 + 20, y: firstTypeView.imageView.frame.maxY - 15, width: 50, height: 50, text: "Soft boiled")       
    view.addSubview(firstTypeView)

    secondTypeView.setBoiledType()
    secondTypeView.imageView.image = UIImage(named: "Medium boiled")
    secondTypeView.setFrame(x: firstTypeView.optionView.frame.maxX + 25, y: boiledTypeLbl.frame.maxY + 40, width: 91, height: 128)
    secondTypeView.setLbl(x: firstTypeView.frame.width/2 + 20, y: firstTypeView.imageView.frame.maxY - 15, width: 60, height: 50, text: "Medium boiled")
    view.addSubview(secondTypeView)

    thirdTypeView.setBoiledType()
    thirdTypeView.imageView.image = UIImage(named: "Hard boiled")
    thirdTypeView.setFrame(x: secondTypeView.optionView.frame.maxX + 25, y: boiledTypeLbl.frame.maxY + 40, width: 91, height: 128)
    thirdTypeView.setLbl(x: firstTypeView.frame.width/2 + 20, y: firstTypeView.imageView.frame.maxY - 15, width: 50, height: 50, text: "Hard boiled")
    view.addSubview(thirdTypeView)

}
    func addTapGestureToViews() {
     let tapGesture6 = UITapGestureRecognizer(target: self, action: #selector(chooseType))
     let tapGesture7 = UITapGestureRecognizer(target: self, action: #selector(chooseType))
     let tapGesture8 = UITapGestureRecognizer(target: self, action: #selector(chooseType))

      firstTypeView.addGestureRecognizer(tapGesture6)
      secondTypeView.addGestureRecognizer(tapGesture7)
      thirdTypeView.addGestureRecognizer(tapGesture8)
  
    }
     @objc func chooseType(_ gesture: UITapGestureRecognizer) {
       if gesture.view == firstTypeView{
            firstTypeView.optionTapped()
            secondTypeView.viewOriginalState()
            thirdTypeView.viewOriginalState()
        } else if gesture.view == secondTypeView {
            secondTypeView.optionTapped()
            firstTypeView.viewOriginalState()
            thirdTypeView.viewOriginalState()
        } else if gesture.view == thirdTypeView {
            thirdTypeView.optionTapped()
            firstTypeView.viewOriginalState()
            secondTypeView.viewOriginalState()
        }
    }

First firstTypeView, secondTypeView, thirdTypeView are instances of CustomView class.

class CustomView : UIView {

    let optionView = UIView()
    var optionTitle = UILabel()
    var imageView = UIImageView()

     override init(frame: CGRect) {
            super.init(frame: frame)
            self.isUserInteractionEnabled = true
        }
    
    required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
            self.isUserInteractionEnabled = true
        }

     func setBoiledType () {   
       addSubview(optionView)
        optionView.widthAnchor.constraint(equalToConstant: 100.0).isActive = true
        optionView.heightAnchor.constraint(equalToConstant: 128.0).isActive = true
        optionView.layer.masksToBounds = false
        optionView.layer.borderWidth = 1.0
        optionView.layer.borderColor = UIColor(named: "inActive")?.cgColor
        optionView.layer.cornerRadius = 10
        optionView.layer.shadowColor = UIColor.black.cgColor
        optionView.layer.shadowOffset = CGSizeMake(0, 5)
        optionView.backgroundColor = .white
        optionView.layer.shadowOpacity = 0.1
        optionView.layer.shadowRadius = 5

        imageView.frame = CGRect(x: -43, y: -40, width: 180, height: 126)
        optionView.addSubview(imageView)
        optionView.addSubview(optionTitle)

    }

//Setting frame of UIView
   func setFrame (x: CGFloat, y: CGFloat, width: CGFloat, height: CGFloat) {
   optionView.frame = CGRect(x: x, y: y, width: width, height: height)

    }
    //Setting label of UIView
   func setLbl (x: CGFloat, y: CGFloat, width: CGFloat, height: CGFloat, text: String) {
        optionTitle.frame = CGRect(x: x, y: y, width: width, height: height)
        optionTitle.text = text
        optionTitle.font = UIFont(name: "SourceSansPro-Regular", size: 15)
        optionTitle.numberOfLines = 2
    }

    func optionTapped() {
        optionView.layer.borderColor = UIColor(named: "active")?.cgColor
        optionTitle.textColor = UIColor(named: "active")
        optionTitle.font = UIFont(name: "SourceSansPro-Bold", size: 15.0)
    }
    
    func viewOriginalState() {
        optionView.layer.borderColor = UIColor(named: "inActive")?.cgColor
        optionView.layer.cornerRadius = 10
        optionView.layer.borderWidth = 1.0
        optionTitle.font = UIFont(name: "SourceSansPro-Regular", size: 15)
        optionTitle.textColor = .lightGray
    }

I want the border color, font, and text color to change their appearances when they are clicked but it's not happening, no reaction even if the user interaction is true. Here is the picture screenshot. As you see every UIview in the other section working fine but not in the Boiled Type Section.

My question is how to make the selector work.

1

There are 1 best solutions below

3
matt On

I'm going to guess (anticipating your showing us your real code) that your CustomView has no size. Therefore it is just a point at the top left corner of its superview. The result is that you see its subviews but they are not tappable (because a subview outside of its superview is not tappable).