未调用 UITapGestureRecognizer 选择器
Posted
技术标签:
【中文标题】未调用 UITapGestureRecognizer 选择器【英文标题】:UITapGestureRecognizer selector not being invoked 【发布时间】:2017-04-12 02:46:44 【问题描述】:在我的主窗口的根视图控制器类中,我设置了一个 UITapGestureRecognizer 属性。在调用重写的 viewDidLoad 函数期间,我已通过 addGestureRecognizer 方法将此属性添加到图像属性中。我还将 image.isUserInteractionEnabled 设置为 true。
override func viewDidLoad()
image.addGestureRecognizer(tap)
image.isUserInteractionEnabled = true
self.view.addSubview(image)
var tap = UITapGestureRecognizer(target: self, action: #selector(imagePressed(_ :)))
遗憾的是,这不会导致运行时调用 imagePressed()。令我困惑的是以下代码产生了预期的结果。
override func viewDidLoad()
var tap = UITapGestureRecognizer(target: self, action:#selector(imagePressed(_ :)))
image.addGestureRecognizer(tap)
image.isUserInteractionEnabled = true
self.view.addSubview(image)
所以我的问题是,为什么在第一种情况下不调用 UITapGestureRecognizer 的选择器?
使用 Swift 3 和 Xcode 8.2.1
【问题讨论】:
如果您发布的代码是正确的,您希望第一次尝试如何工作?你tap
声明不在任何函数中!它属于在viewDidLoad()中。
点击是我的视图控制器类的属性
我可能是错的,但我从未见过也没有听说过让手势识别器成为视图的属性。我不认为它可以做到。
你知道为什么吗?我的意思是,就像你说的,我看到的所有示例都表明识别器是在本地创建的,但我想知道这两种情况之间的区别是什么。
我猜它 - 至少 - 与变量范围有关。考虑一下,手势的 instance 怎么会附加到尚未加载的 class 上? (我敢肯定,更博学的开发人员会对此评论嗤之以鼻,但近 40 年的 IT 生涯意味着我有办法将“自上而下”转换为 OOP。)换句话说,UIViewController 生命中最早的事件是 viewDidLoad - 为什么期望你在“上面”定义的所有东西都能简单地工作?是的,我希望编译器会停止大多数事情,但也许不会。如果 self 还不存在,你如何附加一些东西呢?
【参考方案1】:
我认为这里的问题是addGestureRecognizer
。
尝试将您的viewDidLoad
更改为:
override func viewDidLoad()
var tap = UITapGestureRecognizer(target: self, action:#selector(imagePressed(_ :)))
image.isUserInteractionEnabled = true
self.view.addSubview(image)
image.addGestureRecognizer(tapGesture)
【讨论】:
哦,哎呀。这就是我打算写的,所以问题仍然存在 那么,你更新了吗?但是imagePressed
仍然没有调用?
嗯,我的实际代码有正确的语法,所以是的,imagePressed 仍然没有被调用。
你能在addSubview
之后试试addGestureRecognizer
吗?就像我的回答一样?
是的,刚试过,第一种情况仍然无效,第二种情况仍然有效【参考方案2】:
对于未来的读者:
第一种情况不起作用,因为tap
在加载视图控制器的视图之前被实例化,尽管是在函数声明之后编写的。在调用viewDidLoad()
之前,self.view
是nil
,并且因为UITapGestureRecognizer
依赖于视图,所以手势识别器不起作用。
主要内容:在视图控制器的视图添加到视图层次结构之后和都创建和添加手势识别器。
【讨论】:
以上是关于未调用 UITapGestureRecognizer 选择器的主要内容,如果未能解决你的问题,请参考以下文章
未完全加载单元格时未调用 didSelectItemAtIndexPath
numberOfRowsInSection 已调用但 cellForRowAt 未调用
调用 textFieldShouldBeginEditing,未调用 textFieldDidBeginEditing