iOS导航栏左侧按钮左移后左侧区域点击无响应修复咨询
解决导航栏左侧按钮左移后点击区域失效的问题
这个问题我之前也碰到过,根源在于你用transform把按钮向左平移15pt后,按钮的容器视图suggestButtonContainer的范围没跟上——它还是用按钮原来的frame创建的,导致按钮左移出去的那部分区域不在容器的 bounds 范围内。而导航栏的UIBarButtonItem是通过它的自定义视图(也就是这个容器)的范围来识别点击区域的,超出容器范围的点击自然不会触发按钮事件。
下面给你几种靠谱的修复方案:
方案1:直接调整按钮在容器内的位置(推荐)
不用transform平移,直接把按钮的x坐标设为负数,同时扩大容器的宽度来覆盖按钮左移后的全部区域:
let suggestButton = UIButton(type: .custom) // 直接将按钮的x设为-15,替代transform平移 suggestButton.frame = CGRect(x: -15, y: 0, width: 60, height: 40) suggestButton.setImage(backImage, for: .normal) suggestButton.backgroundColor = .green suggestButton.imageEdgeInsets = UIEdgeInsets(top: 10.0, left: 5.0, bottom: 10.0, right: 35) suggestButton.addTarget(self, action: #selector(showPopover(sender:)), for: .touchUpInside) // 容器宽度设为按钮宽度+左移距离,确保覆盖按钮全部区域 let suggestButtonContainer = UIView(frame: CGRect(x: 0, y: 0, width: 60 + 15, height: 40)) suggestButtonContainer.addSubview(suggestButton) let suggestButtonItem = UIBarButtonItem(customView: suggestButtonContainer) navigationItem.leftBarButtonItem = suggestButtonItem
方案2:保留transform,但调整容器frame
如果一定要用transform,可以先计算按钮变换后的实际frame,再把容器的frame设为这个范围,最后重置按钮的transform(让容器来承担位移):
let suggestButton = UIButton(type: .custom) suggestButton.frame = CGRect(x: 0, y: 0, width: 60, height: 40) suggestButton.setImage(backImage, for: .normal) suggestButton.backgroundColor = .green suggestButton.imageEdgeInsets = UIEdgeInsets(top: 10.0, left: 5.0, bottom: 10.0, right: 35) suggestButton.addTarget(self, action: #selector(showPopover(sender:)), for: .touchUpInside) // 先计算变换后的按钮frame let transform = CGAffineTransform(translationX: -15, y: 0) let transformedFrame = suggestButton.frame.applying(transform) // 容器用变换后的frame let suggestButtonContainer = UIView(frame: transformedFrame) suggestButtonContainer.addSubview(suggestButton) // 重置按钮的transform,让容器的位置来实现左移效果 suggestButton.transform = .identity let suggestButtonItem = UIBarButtonItem(customView: suggestButtonContainer) navigationItem.leftBarButtonItem = suggestButtonItem
方案3:给容器添加点击手势转发
如果不想调整frame,可以给容器添加点击手势,手动触发按钮的点击事件:
let suggestButton = UIButton(type: .custom) suggestButton.frame = CGRect(x: 0, y: 0, width: 60, height: 40) suggestButton.setImage(backImage, for: .normal) suggestButton.backgroundColor = .green suggestButton.imageEdgeInsets = UIEdgeInsets(top: 10.0, left: 5.0, bottom: 10.0, right: 35) suggestButton.addTarget(self, action: #selector(showPopover(sender:)), for: .touchUpInside) suggestButton.transform = CGAffineTransform(translationX: -15, y: 0) let suggestButtonContainer = UIView(frame: suggestButton.frame) suggestButtonContainer.addSubview(suggestButton) // 给容器添加点击手势,触发按钮的点击逻辑 let tapGesture = UITapGestureRecognizer(target: self, action: #selector(containerTapped)) suggestButtonContainer.addGestureRecognizer(tapGesture) let suggestButtonItem = UIBarButtonItem(customView: suggestButtonContainer) navigationItem.leftBarButtonItem = suggestButtonItem // 手势触发的方法,调用按钮的点击事件 @objc func containerTapped() { showPopover(sender: suggestButton) }
核心逻辑总结:确保UIBarButtonItem的自定义视图(容器)的范围完全覆盖按钮的可点击区域,因为导航栏只会响应自定义视图范围内的点击操作。
内容的提问来源于stack exchange,提问作者DIMPAL BHENDARKAR
相关产品推荐
相关产品推荐

