事件传递机制面试题

IOS面试题(UIView) ----- 事件传递机制 - 简书

iOS面试题:事件传递和响应机制


iOS 事件传递面试题
 

iOS 事件传递面试题_ios 时间传递的面试题-CSDN博客

面试题1:  

iOS页面上有一个UIbutton a,有点击事件afunc;上层有个全屏的视图 B,有点击事件bfunc;正常点击a,响应的是B。怎么才能让B不响应,A响应?

  1. 事件传递:
    如果全屏视图B是一个普通视图(非按钮等控件),你可以在它的视图控制器中复写touchesBegan(_:with:)touchesMoved(_:with:)touchesEnded(_:with:)touchesCancelled(_:with:)方法,并在这些方法中对触摸位置进行检查。如果触摸位置在UIButton a的范围内,你可以将事件直接传递给UIButton a。

  2. 重写全屏视图B的point(inside:with:)方法:
    通过调整视图层级,确保UIButton a在视图层次中位于全屏视图B之上。这样,点击事件自然会首先传递给UIButton a。可以通过调用bringSubviewToFront(_:)方法来确保UIButton a位于最前面:

    class FullscreenView: UIView {
        weak var buttonA: UIButton?
        
        override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
            // 检查触摸点是否在buttonA内部
            if let buttonA = buttonA, buttonA.frame.contains(point) {
                // 如果在buttonA内,返回false以允许buttonA响应事件
                return false
            }
            // 否则,返回true以允许全屏视图B响应事件
            return true
        }
    }
  3. 使用手势识别器:

    方式一:在这个方案中,我们实现了UIGestureRecognizerDelegategestureRecognizer(_:shouldReceive:)方法,以便在触摸发生在UIButton a上时返回false,这样全屏视图B上的手势识别器就不会接收到这个触摸事件。

    以上是实现特定区域事件穿透的几种方案。你可以根据具体的应用场景和需求,选择最适合你的方法。

    class ViewController: UIViewController, UIGestureRecognizerDelegate {
        @IBOutlet var buttonA: UIButton!
        @IBOutlet var fullscreenView: UIView!
        
        override func viewDidLoad() {
            super.viewDidLoad()
            let tapGesture = UITapGestureRecognizer(target: self, action: #selector(bFunc))
            tapGesture.delegate = self
            fullscreenView.addGestureRecognizer(tapGesture)
        }
        
        @objc func aFunc(sender: UIButton) {
            // 处理buttonA点击事件
        }
        
        @objc func bFunc(gesture: UITapGestureRecognizer) {
            // 处理全屏视图B点击事件
        }
        
        // UIGestureRecognizerDelegate方法
        func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
            if touch.view == buttonA {
                // 如果触摸的视图是buttonA,不让全屏视图B的手势识别器接收这个触摸事件
                return false
            }
            return true
        }
    }
    

    方式二:为全屏视画B添加一个UITapGestureRecognizer,并在其回调方法中检查触摸点是否在UIButton a的边界内。如果是,则不执行bfunc,反之则执行bfunc。示例代码如下:

    let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(viewTapped(_:)))
    B.addGestureRecognizer(tapRecognizer)
    
    @objc func viewTapped(_ recognizer: UITapGestureRecognizer) {
        let location = recognizer.location(in: B)
        if a.frame.contains(location) {
            // 触摸点在UIButton a内,你可以在这里调用afunc()
        } else {
            // 触摸点不在UIButton a内,执行bfunc()
            bfunc()
        }
    }
    
  4. 条件性地拦截事件:      
    如果你不能改变视图层级,并且需要更细致地控

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值