自定义UITableViewCell子视图无法识别Tap手势问题求助
自定义UITableViewCell子视图Tap手势无法触发问题
在iOS开发中,我使用自定义MonthlyViewCell作为UITableView的单元格,该单元格内包含多个UIStackView,每个StackView中都有UIImageView类型的符号视图。我希望给这些符号视图添加Tap手势识别,但只有单元格自身的手势能正常工作,所有子视图(符号视图、StackView)的手势都无法触发,断点显示手势触发方法从未被调用。
已尝试的调试操作
- 为所有相关视图设置
isUserInteractionEnabled = true; - 调整子视图frame,确保其完全包含在父视图范围内;
- 修改手势创建逻辑,将
UITapGestureRecognizer实例的创建移至循环内部,为每个符号视图单独分配手势实例; - 检查约束配置,避免StackView超出父视图范围;
相关代码
MonthlyViewCell完整代码
class MonthlyViewCell: UITableViewCell { private let someSymbol: UIImageView = { guard let image = UIImage(systemName: "j.circle.fill") else {return nil} let config = UIImage.SymbolConfiguration(pointSize: 27) let newImage = image.applyingSymbolConfiguration(config) let view = UIImageView(image: newImage) view.frame = CGRect(x: 0, y: 0, width: 10, height: 10) view.contentMode = .scaleAspectFit view.tag = 1 view.isUserInteractionEnabled = true return view }() . . // other symbols private var delegate: MonthlyViewCellDelegate? private var stackViewOne = UIStackView() private var stackViewTwo = UIStackView() private var stackViewThree = UIStackView() override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) commonInit() } required init?(coder: NSCoder) { super.init(coder: coder) } private func commonInit() { bounds = CGRect(x: 0, y: 0, width: 320, height: 120) frame = bounds print(frame) configureSubViews() addSubview(stackViewOne) addSubview(stackViewTwo) addSubview(stackViewThree) //addTargetToSymbols() activateConstraints() stackViewOne.frame = CGRect(x: 0, y: 0, width: frame.width-1, height: 15) stackViewTwo.frame = CGRect(x: 0, y: 0, width: frame.width-1, height: 15) stackViewThree.frame = CGRect(x: 0, y: 0, width: frame.width-1, height: 15) let gestureRecognizer = UITapGestureRecognizer() gestureRecognizer.addTarget(self, action: #selector(testTapped(sender:))) stackViewTwo.addGestureRecognizer(gestureRecognizer) } private func configureSubViews() { stackViewOne.translatesAutoresizingMaskIntoConstraints = false stackViewTwo.translatesAutoresizingMaskIntoConstraints = false stackViewThree.translatesAutoresizingMaskIntoConstraints = false stackViewOne.axis = .horizontal stackViewTwo.axis = .horizontal stackViewThree.axis = .horizontal stackViewOne.spacing = 60 stackViewTwo.spacing = 60 stackViewThree.spacing = 60 let viewsOne = [januarySymbol, februarySymbol, marchSymbol, aprilSymbol] let viewsTwo = [maySymbol, juneSymbol, julySymbol, augustSymbol] let viewsThree = [septemberSymbol, octoberSymbol, novemberSymbol, decemberSymbol] let stackViews = [stackViewOne,stackViewTwo,stackViewThree] for one in viewsOne { stackViewOne.addArrangedSubview(one!) } for two in viewsTwo { stackViewTwo.addArrangedSubview(two!) } for three in viewsThree { stackViewThree.addArrangedSubview(three!) } /*for view in stackViews { bringSubviewToFront(view) }*/ } private func activateConstraints() { let array: [NSLayoutConstraint] = [ stackViewOne.centerXAnchor.constraint(equalTo: safeAreaLayoutGuide.centerXAnchor), stackViewTwo.centerXAnchor.constraint(equalTo: safeAreaLayoutGuide.centerXAnchor), stackViewThree.centerXAnchor.constraint(equalTo: safeAreaLayoutGuide.centerXAnchor), stackViewOne.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor, constant: 25), stackViewTwo.topAnchor.constraint(equalTo: stackViewOne.bottomAnchor, constant: 25), stackViewThree.topAnchor.constraint(equalTo: stackViewTwo.bottomAnchor, constant: 25) ] NSLayoutConstraint.activate(array) } private func addTargetToSymbols() { let gestureRecognizer = UITapGestureRecognizer() let symbols: [UIImageView?] = [januarySymbol, februarySymbol, marchSymbol, aprilSymbol, maySymbol, juneSymbol, julySymbol, augustSymbol, septemberSymbol, novemberSymbol, decemberSymbol] for symbol in symbols { guard let symbol = symbol else {return} gestureRecognizer.addTarget(self, action: #selector(monthSymbolTapped(sender:))) symbol.addGestureRecognizer(gestureRecognizer) bringSubviewToFront(symbol) } } @objc func testTapped(sender: UITapGestureRecognizer) { print("tapped") } func setDelegate(delegate: MonthlyViewCellDelegate) { self.delegate = delegate } }
补充说明
- 委托方法已在视图控制器中实现,控制器的View为UITableView,单元格在
cellForRowAt方法中初始化。 - 曾尝试修改
addTargetToSymbols方法,为每个符号视图单独创建手势实例,代码如下,但问题仍未解决:
private func addTargetToSymbols() { let symbols: [UIImageView?] = [januarySymbol, februarySymbol, marchSymbol, aprilSymbol, maySymbol, juneSymbol, julySymbol, augustSymbol, septemberSymbol, novemberSymbol, decemberSymbol] for symbol in symbols { guard let symbol = symbol else {return} let gestureRecognizer = UITapGestureRecognizer() gestureRecognizer.addTarget(self, action: #selector(monthSymbolTapped(sender:))) symbol.addGestureRecognizer(gestureRecognizer) bringSubviewToFront(symbol) } }
手势触发方法代码
@objc func monthSymbolTapped(sender: UIGestureRecognizer) { print("tst") guard let tag = sender.view?.tag else {return} switch tag { case 1: delegate?.pushToYearlyVisits(month: tag) // other cases default: return } }
内容的提问来源于stack exchange,提问作者Holmes
相关产品推荐
相关产品推荐

