Swift中自定义UIView添加UITapGestureRecognizer点击手势不生效
问题核心原因
你的手势无法触发,本质是视图加载时机不对导致的视图层级实际响应区域和可见区域不匹配,和circleButton本身的isUserInteractionEnabled属性无关:
- 你在
commonInit方法中加载XIB根视图customBar时,仅用初始化阶段的bounds给customBar赋值了frame,没有设置布局自适应规则。当Storyboard完成Auto Layout布局、CustomBottomBar的实际尺寸发生变化时,customBar的frame不会同步更新,最终customBar及其子视图circleButton的实际响应区域,和你屏幕上看到的渲染位置完全错位,甚至circleButton完全落在父视图的bounds范围外。
UIKit触摸事件传递规则:如果子视图的展示区域超出父视图的bounds范围,点击该区域时父视图不会命中这个子视图,子视图绑定的所有手势都无法触发。
- 你在
commonInit中打印的circleButton.frame是XIB文件中存储的初始尺寸,不是Auto Layout执行完成后的真实运行尺寸,这个打印值没有参考意义。
修复步骤
- 给加载的XIB根视图开启自适应尺寸,保证它能始终撑满
CustomBottomBar:
private func commonInit() { if let customBar = Bundle.main.loadNibNamed("CustomBottomBar", owner: self, options: nil)?[0] as? UIView { customBar.frame = bounds // 新增这行,让XIB根视图随父视图自动调整宽高 customBar.autoresizingMask = [.flexibleWidth, .flexibleHeight] addSubview(customBar) circleButton.clipsToBounds = true circleButton.isUserInteractionEnabled = true let tapGesture = UITapGestureRecognizer(target: self, action: #selector(onAddButtonClicked)) circleButton.addGestureRecognizer(tapGesture) } }
- 把所有依赖视图尺寸的配置(比如圆角计算)移到
layoutSubviews方法中,这个方法执行时视图已经完成布局,拿到的frame是真实值:
override func layoutSubviews() { super.layoutSubviews() circleButton.layer.borderColor = UIColor.black.cgColor circleButton.layer.borderWidth = 2 // 移到这里计算圆角,避免初始尺寸不准导致的圆形变形 circleButton.layer.cornerRadius = circleButton.frame.height / 2 }
- 检查XIB中
circleButton的所有上层父视图(contentView、bottomBarView、XIB根视图customBar)的isUserInteractionEnabled属性,确保没有被误关闭——UIView默认该属性为true,只要上层任意一个父视图关闭了交互,子视图的手势就不会响应。
修复后运行,点击circleButton即可正常触发onAddButtonClicked的打印逻辑。
内容的提问来源于stack exchange,提问作者H1rouge
相关产品推荐
相关产品推荐

