Swift中自定义UIView添加UITapGesture无响应问题求助
问题:自定义UIView尺寸为0导致手势无响应,手动设置尺寸后显示异常
自定义视图代码(CustomView.swift)
class CustomView: UIView { @IBOutlet weak var titleLabel: UILabel! @IBOutlet weak var childView: UIView! @IBOutlet weak var buttonView: UIView! override init(frame: CGRect) { super.init(frame: frame) dprint("CustomView init frame") viewInit() } required init?(coder: NSCoder) { super.init(coder: coder) dprint("CustomView init coder") viewInit() } func viewInit() { let xibView = Bundle.main.loadNibNamed("CustomView", owner: self, options: nil)![0] as! UIView addSubview(xibView) } }
ViewController中调用代码
let cv = CustomView() self.view.addSubview(cv) HelperXib.setCenteredXibContraints(cv, self.view) struct HelperXib { static func setCenteredXibContraints(_ sameView:UIView, _ parentView: UIView) { // 用于居中显示的错误视图,例如:AlertNoPixKey sameView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ sameView.centerXAnchor.constraint(equalTo: parentView.centerXAnchor), sameView.centerYAnchor.constraint(equalTo: parentView.centerYAnchor), ]) } }
手势无响应问题
给buttonView添加点击手势后无响应:
let tap2 = UITapGestureRecognizer(target: self, action: #selector(ChargeEnterDataViewController.redirectToMyKeys(_:)) ) cv.buttonView.addGestureRecognizer(tap2) cv.buttonView.isUserInteractionEnabled = true
编辑1:发现视图尺寸异常
打印视图尺寸:
print("cv.frame.size: \(cv.frame.size)") print("cv.buttonView.frame.size: \(cv.buttonView.frame.size)")
控制台输出:
cv.frame.size: (0.0, 0.0) cv.buttonView.frame.size: (240.0, 49.0)
cv的宽高为0,推测是手势无响应的核心原因。
编辑2:手动设置尺寸后显示异常
尝试手动设置cv尺寸:
let cv = CustomView() cv.frame.size.width = UIScreen.main.bounds.width cv.frame.size.height = UIScreen.main.bounds.height cv.backgroundColor = .blue
结果仅显示部分视图,寻求解决方法。
解决方案
1. 修复CustomView的Xib加载布局逻辑
当前viewInit()仅将xib视图添加到CustomView,但未设置约束让xib视图填满父视图,导致CustomView无法根据xib内容自动计算尺寸。修改viewInit():
private var xibView: UIView! func viewInit() { guard let loadedView = Bundle.main.loadNibNamed("CustomView", owner: self, options: nil)?.first as? UIView else { return } xibView = loadedView xibView.translatesAutoresizingMaskIntoConstraints = false addSubview(xibView) // 添加约束让xib视图完全填满CustomView NSLayoutConstraint.activate([ xibView.topAnchor.constraint(equalTo: self.topAnchor), xibView.leadingAnchor.constraint(equalTo: self.leadingAnchor), xibView.trailingAnchor.constraint(equalTo: self.trailingAnchor), xibView.bottomAnchor.constraint(equalTo: self.bottomAnchor) ]) }
2. 给CustomView补充尺寸约束
之前仅设置居中约束,未定义宽高,导致CustomView无法确定自身尺寸。可选择以下两种方式:
方式A:直接设置固定宽高约束
修改HelperXib的方法,添加宽高约束(数值根据实际需求调整):
struct HelperXib { static func setCenteredXibContraints(_ sameView:UIView, _ parentView: UIView) { sameView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ sameView.centerXAnchor.constraint(equalTo: parentView.centerXAnchor), sameView.centerYAnchor.constraint(equalTo: parentView.centerYAnchor), sameView.widthAnchor.constraint(equalToConstant: 320), sameView.heightAnchor.constraint(equalToConstant: 240) ]) } }
方式B:让CustomView自动适配内容尺寸
重写intrinsicContentSize,让CustomView根据xib内容自动计算尺寸:
override var intrinsicContentSize: CGSize { return xibView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize) }
此时ViewController中仅保留居中约束即可,CustomView会自动适配内容尺寸。
3. 验证手势响应
完成上述修改后,cv的尺寸会正常渲染,buttonView的点击手势即可正常触发。
内容的提问来源于stack exchange,提问作者fabiobh
相关产品推荐
相关产品推荐

