iOS中AVPlayer上层UIButton点击事件无法触发的问题求助
这个问题我之前也碰到过,核心原因是你混淆了UIView响应链和CALayer图层层级的区别,导致触摸事件根本传不到你的按钮上。
问题根源分析
你代码里把btn.layer添加到了playerLayer这个CALayer中,但UIButton作为UIView,并没有被添加到任何UIView的层级里——只有它的图层在图层树中,而iOS的触摸事件是通过UIView的响应链来传递的,CALayer本身并不参与触摸事件的处理。所以点击时系统找不到这个按钮,自然触发不了点击事件;而直接调用sendActions(for:)是绕过了触摸事件传递流程,直接调用目标方法,所以能正常响应。
两种修复方案
方案1:直接将UIButton添加到视图层级(适合当前用AVPlayerLayer的场景)
把你代码里的playerLayer.addSublayer(btn.layer)替换成将按钮作为子视图添加到当前控制器的view中,同时确保按钮在播放器图层的上方:
override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. guard let url = URL(string: "https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_adv_example_hevc/master.m3u8") else { return } // Create an AVPlayer, passing it the HTTP Live Streaming URL. let player = AVPlayer(url: url) // Create a new AVPlayerViewController and pass it a reference to the player. let playerLayer = AVPlayerLayer(player: player) playerLayer.frame = self.view.bounds let btn = UIButton(type: .roundedRect) btn.backgroundColor = UIColor.yellow btn.setTitle("Do stuff 1", for: .normal) btn.frame = CGRect(x: 0, y: 330, width: 300, height: 300) btn.addTarget( self, action: #selector(self.pressButton(button:)), for: .touchUpInside) // 关键修改:将按钮添加到视图层级,而非仅仅添加图层 self.view.addSubview(btn) // 确保按钮在播放器图层上方(可选,默认视图层级会在图层之上,但保险起见可以加上) self.view.bringSubviewToFront(btn) self.view.layer.addSublayer(playerLayer) player.play() }
方案2:使用AVPlayerViewController的contentOverlayView(官方推荐方式)
如果你可以改用AVPlayerViewController来管理播放器,官方专门提供了contentOverlayView属性,用于添加自定义叠加UI,它会自动处理层级和交互问题:
override func viewDidLoad() { super.viewDidLoad() guard let url = URL(string: "https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_adv_example_hevc/master.m3u8") else { return } let player = AVPlayer(url: url) let playerVC = AVPlayerViewController() playerVC.player = player playerVC.view.frame = self.view.bounds // 将AVPlayerViewController添加为子控制器 self.addChild(playerVC) self.view.addSubview(playerVC.view) playerVC.didMove(toParent: self) let btn = UIButton(type: .roundedRect) btn.backgroundColor = .yellow btn.setTitle("Do stuff 1", for: .normal) btn.frame = CGRect(x: 0, y: 330, width: 300, height: 300) btn.addTarget(self, action: #selector(pressButton(button:)), for: .touchUpInside) // 使用官方提供的叠加视图添加按钮,无需担心交互问题 playerVC.contentOverlayView?.addSubview(btn) player.play() }
额外注意点
- 不需要手动设置
btn.isUserInteractionEnabled = true,UIButton默认就是开启用户交互的。 - 如果使用方案1,若发现按钮还是被播放器遮挡,可以调整
btn.layer.zPosition的值,设置为比playerLayer.zPosition大的数值,确保按钮图层在最上方。
内容的提问来源于stack exchange,提问作者phoenix2010
相关产品推荐
相关产品推荐

