【问题标题】:How to continue touches/gesture to next view controller如何继续触摸/手势到下一个视图控制器
【发布时间】:2015-01-23 16:44:10
【问题描述】:

我有兴趣在我的项目中开发类似 Snapchat 的手势,其中一个触摸事件将调用一个新的视图控制器,并且只有当用户的手指仍然向下时,视图控制器才可见。

目前,我设法实现了一个wildcard gesture recognizer,其中包含touchesBegantouchesMovedtouchesEnded 的回调块。

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 会调用一个新的视图控制器,而不仅仅是一个新的视图吗?
  • 这是我的猜测,所以我的问题是关于继续触摸视图控制器

标签: ios swift


【解决方案1】:

好吧,您可以获取触摸 NSSetUIEvent 并通过属性将它们传递给新控制器,但这可能没有必要,因为只要用户移动手指,操作系统就会发送新的触摸事件。

我相信窗口中的任何控制器都应该接收新事件。因此,您可以将“didPress”布尔值传递给新控制器,然后侦听要在新控制器上调用的touchesEnded 委托。这应该会给你想要的互动。

请记住,这是即兴表演,因此您可能需要稍微玩一下。

【讨论】:

  • 它不会触发 touchesEnded 没有触发 touchesBegan 先或手动强制它开始
  • 嗯,如何添加新的视图控制器?您是将其添加到导航堆栈中,还是将其添加为子视图控制器?您是否尝试过使用子视图控制器?
  • 我不得不使用子视图控制器来实现这一点
【解决方案2】:

我的解决方案分为三个步骤:

  1. 从情节提要中实例化您的子视图控制器,请注意您将为视图控制器设置 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")
    }
    
  2. 实现一个通配符手势识别器,它在触摸开始时执行touchesBeganBlocktable view cell 或您希望在父视图控制器中附加此手势的任何其他对象,例如以下:

    var touchesBeganCallback : ((NSSet, UIEvent)-> Void)?
    func touchesBegan(touches: NSSet!, withEvent event: UIEvent!) {
      if (touchesBeganCallback != nil){
        touchesBeganCallback!(touches,event)
      }
    }
    

    这个touchesBeganBlock 将调用实例化视图控制器的函数(步骤 1 中的代码)

  3. 最后,当触摸结束时,执行一个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 的可读性问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-14
  • 1970-01-01
  • 2016-09-13
  • 1970-01-01
相关资源
最近更新 更多