You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 22:55:11