Home > Software design >  UILabel not clickable in stack view programmatically created Swift
UILabel not clickable in stack view programmatically created Swift

Time:12-27

My question and code is based on enter image description here

Code is as follows:

 override func viewDidLoad() {
    super.viewDidLoad()
   
    let stackView = UIStackView()
    stackView.axis = .vertical
    stackView.distribution = .fill
    stackView.alignment = .top
    stackView.spacing = 4

    let label1 = UILabel()
    label1.numberOfLines = 0
    label1.text = "Row 1"
    label1.tag = 11
    setTapListener(label1)
    stackView.addArrangedSubview(label1)
    
    let label2 = UILabel()
    label2.numberOfLines = 0
    label2.text = "Row 2"
    label2.tag = 22
    setTapListener(label2)
    stackView.addArrangedSubview(label2)

    stackView.translatesAutoresizingMaskIntoConstraints = false
    self.view.addSubview(stackView)
    stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    stackView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    stackView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
    stackView.heightAnchor.constraint(equalToConstant: 300).isActive = true
}

public func setTapListener(_ label: UILabel){
    let tapGesture: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(tapGestureMethod(_:)))
    tapGesture.numberOfTapsRequired = 1
    tapGesture.numberOfTouchesRequired = 1
    label.isUserInteractionEnabled = true
    label.addGestureRecognizer(tapGesture)
}

@objc func tapGestureMethod(_ gesture: UITapGestureRecognizer) {
    print(gesture.view?.tag ?? 0)
}

So there is no problem in the code, the problem may be in the UI. The UI may not be refreshed or some other element may be overlapping over it.

1- Try to use the view debugger to check whether any view or element is overlapping over it or not.

2- Try to refresh the layout using layoutSubviews to check whether issue persists or not.

Try to debug the issue with these techniques and solve if you find any. It should work fine.

CodePudding user response:

  1. Read documentation: UITapGestureRecognizer is a class. It means that after calling function all internal variables will be destroyed. So just move let tapGesture: into the class above, do not create it in this function. For example:
   class ScrollView: UIScrollView {

   let tapGesture = {
      let tapGesture = UITapGestureRecognizer(target: self, action: #selector(tapGestureMethod(_:)))
      tapGesture.numberOfTapsRequired = 1
      tapGesture.numberOfTouchesRequired = 1
      label.isUserInteractionEnabled = true
      label.addGestureRecognizer(tapGesture)
      return tapGesture
    }()
    
    } 
  1. Why are you decided to use Label instead of UIButton (with transparence background color and border line)?
  2. Also you can use UITableView instead of stack & labels
  3. Maybe this documentation will help too (it is written that usually in one view better to keep one gesture recognizer): https://developer.apple.com/documentation/uikit/touches_presses_and_gestures/coordinating_multiple_gesture_recognizers
  • Related