Swift:"奇怪"的事件响应链

来源:互联网 发布:sqlserver case when 编辑:程序博客网 时间:2024/06/16 06:13

初学iOS开发的童鞋可能会遇到各式奇怪的问题,这篇博文本猫就为大家介绍其中一个”怪异”问题.

该问题很好重现: 
1.使用xcode新建一个最简单的单vc工程,然后在Storyboard中新建一个destVC.然后从默认创建的VC(姑且称之为initVC)拉一条segue到destVC,并设置该segue ID为”ToDestVC”

2.打开initVC类,只添加2个方法:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {        super.touchesBegan(touches, with: event)        NSLog("在destVC中触摸屏幕却会执行initVC中的这句代码")    }override func viewDidAppear(_ animated: Bool) {    super.viewDidAppear(animated)    performSegue(withIdentifier: "ToDestVC", sender: nil)}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

3.好了,只需要修改这么多.现在编译运行app,由于上面代码的原因,首先initVC被显示,但很快切换到destVC中去.此时在destVC的视图中轻触屏幕,你会发现却是initVC中的touchesBegan方法被触发执行了,是否有些丈二和尚摸不着头脑呢?如果不信,请自行按照以上步骤操作查看结果.

究竟为何会这样呢?其实apple的开发文档中早就说明了原因:

Understanding Event Handling, Responders, and the Responder Chain

如果不想看长篇大论,可以直接看最后这一段话:

这里写图片描述

说的很清楚吧,所以如果不用segue跳转,而是用present跳转到destVC,现象是一样的.

知道了原因如果避免这一”正常”的行为呢?很简单,一种办法是在initVC的prepare方法中关闭initVC.view的交互:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {        if segue.identifier == "ToDestVC"{            view.isUserInteractionEnabled = false        }    }
  • 1
  • 2
  • 3
  • 4
  • 5

另一种方法则是在destVC中重载next属性,将其置为nil,断开responder chain即可:

override var next: UIResponder?{        return nil    }
  • 1
  • 2
  • 3
版权声明:大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处.谢谢! hopy ;)
原创粉丝点击