My question and code is based on
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:
- 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
}()
}
- Why are you decided to use Label instead of UIButton (with transparence background color and border line)?
- Also you can use UITableView instead of stack & labels
- 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