如何让浮动菜单所在透明视图禁用交互但保留按钮交互?
解决浮动菜单容器视图的透明与交互问题
这问题我之前做类似需求时也碰到过,核心是要区分视图背景透明和视图透明度,以及事件传递的拦截逻辑,给你两个关键解决方案:
1. 解决父视图透明但不影响子视图的问题
不要设置父视图的alpha属性(它会作用于整个视图树,包括所有子视图),而是直接把父视图的backgroundColor设为透明:
// Swift yourContainerView.backgroundColor = .clear
// Objective-C yourContainerView.backgroundColor = [UIColor clearColor];
这样父视图本身是完全透明的,但子视图的颜色、透明度都不会受影响,完美达到你要的视觉效果。
2. 解决父视图不接收交互但子视图可交互的问题
直接设置父视图userInteractionEnabled = NO会导致所有子视图也无法响应交互,因为iOS的事件传递是从父视图往下传递的。正确的做法是重写父视图的hitTest方法,让父视图只把事件传递给子视图,自身不处理任何交互:
Swift 实现
class FloatingMenuContainerView: UIView { override init(frame: CGRect) { super.init(frame: frame) setupBaseConfig() } required init?(coder: NSCoder) { super.init(coder: coder) setupBaseConfig() } private func setupBaseConfig() { // 设置背景透明 backgroundColor = .clear } override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { // 倒序遍历子视图(保证层级高的子视图优先响应) for subview in subviews.reversed() { // 把当前点转换为子视图坐标系下的点 let convertedPoint = subview.convert(point, from: self) // 如果点击点在子视图范围内,返回子视图的hitTest结果,让子视图处理交互 if subview.point(inside: convertedPoint, with: event) { return subview.hitTest(convertedPoint, with: event) } } // 如果点击的是父视图空白区域,返回nil,让事件透传到下面的视图(比如tab view) return nil } }
Objective-C 实现
@interface FloatingMenuContainerView : UIView @end @implementation FloatingMenuContainerView - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { [self setupBaseConfig]; } return self; } - (instancetype)initWithCoder:(NSCoder *)coder { self = [super initWithCoder:coder]; if (self) { [self setupBaseConfig]; } return self; } - (void)setupBaseConfig { self.backgroundColor = [UIColor clearColor]; } - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { // 倒序遍历子视图 for (UIView *subview in [self.subviews reverseObjectEnumerator]) { CGPoint convertedPoint = [subview convertPoint:point fromView:self]; if ([subview pointInside:convertedPoint withEvent:event]) { return [subview hitTest:convertedPoint withEvent:event]; } } // 空白区域不处理事件,透传下去 return nil; } @end
最终效果
用这个自定义容器视图来承载你的菜单按钮:
- 容器视图完全透明,菜单按钮的显示不受任何影响
- 点击菜单按钮时,按钮可以正常响应点击、触摸等交互
- 点击容器视图的空白区域时,事件会透传到下面的tab view,不会被容器视图拦截
内容的提问来源于stack exchange,提问作者Wissa
相关产品推荐
相关产品推荐

