如何继续触摸/手势到下一个视图控制器
Posted
技术标签:
【中文标题】如何继续触摸/手势到下一个视图控制器【英文标题】:How to continue touches/gesture to next view controller 【发布时间】:2015-01-23 16:44:10 【问题描述】:我有兴趣在我的项目中开发类似 Snapchat 的手势,其中一个触摸事件将调用一个新的视图控制器,并且只有当用户的手指仍然向下时,视图控制器才可见。
目前,我设法实现了一个wildcard gesture recognizer
,其中包含touchesBegan
、touchesMoved
和touchesEnded
的回调块。
var touchesBeganCallback : ((NSSet, UIEvent)-> Void)?
var touchesMovedCallback : ((NSSet, UIEvent)-> Void)?
var touchesEndedCallback : ((NSSet, UIEvent)-> Void)?
在第二个视图控制器通过 segue 显示之前,我添加了一个 wildcard gesture recognizer
:
destVC.view.addGestureRecognizer(drawWildGestureRecognizer( (touches:NSSet, event:UIEvent) -> Void in
println("LDetailViewController: touches began")
, touchesEndedCallback: (touches:NSSet, event:UIEvent) -> Void in
println("LDetailViewController: touches ended")
))
当然,我的第一个视图控制器已经添加了wildcard gesture recognizer
。但是触摸似乎不会继续到我的第二个视图控制器,即使我再次点击我的第二个视图控制器的视图并且手势识别器正在正确识别触摸。
我还应该在这里做什么?
【问题讨论】:
你知道 Snapchat 的 touch down 会调用一个新的视图控制器,而不仅仅是一个新的视图吗? 这是我的猜测,所以我的问题是关于继续触摸视图控制器 【参考方案1】:好吧,您可以获取触摸 NSSet
和 UIEvent
并通过属性将它们传递给新控制器,但这可能没有必要,因为只要用户移动手指,操作系统就会发送新的触摸事件。
我相信窗口中的任何控制器都应该接收新事件。因此,您可以将“didPress”布尔值传递给新控制器,然后侦听要在新控制器上调用的touchesEnded
委托。这应该会给你想要的互动。
请记住,这是即兴表演,因此您可能需要稍微玩一下。
【讨论】:
它不会触发 touchesEnded 没有触发 touchesBegan 先或手动强制它开始 嗯,如何添加新的视图控制器?您是将其添加到导航堆栈中,还是将其添加为子视图控制器?您是否尝试过使用子视图控制器? 我不得不使用子视图控制器来实现这一点【参考方案2】:我的解决方案分为三个步骤:
从情节提要中实例化您的子视图控制器,请注意您将为视图控制器设置 storyboardID
以便实例化。
postDetailViewController = self.storyboard?.instantiateViewControllerWithIdentifier("showPost") as? LDetailViewController
if postDetailViewController != nil
//add child view
let postDetailView = postDetailViewController!.view
self.view.addSubview(postDetailView)
//add child view controller
self.addChildViewController(postDetailViewController!)
postDetailViewController!.didMoveToParentViewController(self)
else
fatalError("postDetailViewController fails to be created")
实现一个通配符手势识别器,它在触摸开始时执行touchesBeganBlock
到table view cell
或您希望在父视图控制器中附加此手势的任何其他对象,例如以下:
var touchesBeganCallback : ((NSSet, UIEvent)-> Void)?
func touchesBegan(touches: NSSet!, withEvent event: UIEvent!)
if (touchesBeganCallback != nil)
touchesBeganCallback!(touches,event)
这个touchesBeganBlock
将调用实例化视图控制器的函数(步骤 1 中的代码)
最后,当触摸结束时,执行一个touchesEndBlock
,它只是调用一个函数来丢弃你的子视图控制器:
var touchesEndedCallback : ((NSSet, UIEvent)-> Void)?
func touchesEnded(touches: NSSet!, withEvent event: UIEvent!)
if (touchesEndedCallback != nil)
touchesEndedCallback!(touches,event)
在我的,该块执行以下代码:
if (postDetailViewController != nil)
postDetailViewController?.view.removeFromSuperview()
postDetailViewController?.removeFromParentViewController()
postDetailViewController = nil
【讨论】:
您是否有理由使用手势识别器和这些回调,而不是仅在第一个控制器的 self.view 中实现 touchesBegan 和 touchesEnded?这个解决方案不会继续接触下一个视图控制器吗?您只有第一个视图中的一个手势识别器吗? 我想我不太清楚手势识别器的放置位置,它应该放在父视图控制器中。使用自定义手势识别器类的原因是为了使代码更简洁。你可以简单地在你的父视图控制器中调用touchesBegan
。只要您使用子视图控制器,就没有任何区别。
另外,视图控制器中的touchesBegan
会拦截视图控制器中发生的所有触摸。这将导致编写一堆 if 语句来在不同的代码之间切换。无论如何,这只是 imo 的可读性问题。以上是关于如何继续触摸/手势到下一个视图控制器的主要内容,如果未能解决你的问题,请参考以下文章