为何触摸UIView时,UITouchEvent对应的isFirstResponder返回false?
关于第一响应者(First Responder)的概念澄清与问题解答
核心误解纠正
- 第一响应者和触摸事件的目标视图是完全独立的概念,别搞混了。
- UIKit通过点击测试找到触摸点对应的视图(也就是事件的目标视图),会从这个视图开始向上沿响应者链传递事件,但这个过程不会自动把目标视图设为第一响应者。
第一响应者的真正定义
- 第一响应者是响应者链中负责处理特定交互场景的对象,比如文本输入控件(UITextField/UITextView)成为第一响应者时会弹出键盘,或是优先处理菜单、手势等交互。
- 一个对象要成为第一响应者,必须满足两个条件:
- 重写
canBecomeFirstResponder属性,返回true(UIView默认返回false) - 主动调用
becomeFirstResponder()方法
- 重写
你的测试代码问题分析
你在顶层视图中重写touchesBegan时,视图默认不具备成为第一响应者的资格(canBecomeFirstResponder为false),所以即便它是触摸事件的目标视图,isFirstResponder也会是false。
如果要让视图成为第一响应者,修改代码如下:
class TopView: UIView { // 允许视图成为第一响应者 override var canBecomeFirstResponder: Bool { return true } override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { // 主动触发成为第一响应者 _ = becomeFirstResponder() if touches.first?.view?.isFirstResponder == true { print("Top View is firstResponder ") } super.touchesBegan(touches, with: event) } }
内容的提问来源于stack exchange,提问作者Sudhir kumar
相关产品推荐
相关产品推荐

