将现有和活动的手势识别器传递给模态视图控制器
Posted
技术标签:
【中文标题】将现有和活动的手势识别器传递给模态视图控制器【英文标题】:Passing an existing and active gesture recognizer to a modal view controller 【发布时间】:2015-04-09 17:50:30 【问题描述】:我想长按启动模态视图,然后在取消长按时关闭模态视图。我该怎么做?
我尝试将 longPressRecognizer 传递给模态视图并 将其设置为委托,但这不起作用。 我尝试了一些更简单的方法 - 检测 touchesEnded,这意味着在模态视图中触摸结束,但这也不会触发。有没有办法告诉模态视图一个手势已经开始?我希望您识别此手势或触摸的结束/取消?
ViewController.swift
import UIKit
class ViewController: UIViewController, UIGestureRecognizerDelegate
var buttonView:UIView!
var longPressRecognizer:UILongPressGestureRecognizer!
override func viewDidLoad()
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.longPressRecognizer = UILongPressGestureRecognizer(target: self, action: "longPressed:")
self.longPressRecognizer.delegate = self
self.view.addGestureRecognizer(self.longPressRecognizer)
// Add a button
buttonView = UIView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: 100))
buttonView.userInteractionEnabled = true;
buttonView.backgroundColor = UIColor.grayColor()
self.view.addSubview(buttonView)
func longPressed(recognizer: UILongPressGestureRecognizer)
let point: CGPoint = recognizer.locationInView(self.view)
if let pressedView = self.view.hitTest(point, withEvent: nil)
if pressedView == self.buttonView
switch recognizer.state
case .Began:
NSLog("long pressed - Began")
var mediaViewController = MediaViewController()
self.presentViewController(mediaViewController, animated: false, completion: nil)
case .Cancelled:
NSLog("long pressed - Cancelled")
case .Ended:
NSLog("long pressed - Ended")
default:
break
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
MediaViewController.swift
import UIKit
class MediaViewController: UIViewController, UIGestureRecognizerDelegate
var longPressRecognizer:UILongPressGestureRecognizer!
override func viewDidLoad()
super.viewDidLoad()
self.view.backgroundColor = UIColor.lightGrayColor()
self.longPressRecognizer = UILongPressGestureRecognizer(target: self, action: "longPressed:")
self.longPressRecognizer.delegate = self
self.view.addGestureRecognizer(self.longPressRecognizer)
func longPressed(recognizer: UILongPressGestureRecognizer)
switch recognizer.state
case .Began:
NSLog("long pressed - Began")
case .Cancelled:
NSLog("long pressed - Cancelled")
case .Ended:
NSLog("long pressed - Ended")
self.dismissViewControllerAnimated(false, completion: nil)
default:
break
override func touchesBegan(touches: NSSet, withEvent event: UIEvent)
NSLog("touches began")
override func touchesEnded(touches: NSSet, withEvent event: UIEvent)
NSLog("touches ended")
【问题讨论】:
一个笨拙的解决方法可能是引用模态视图控制器并创建一个viewController
可以调用并传递触摸事件信息的方法。您需要在您的viewController
实现中处理.Changed
识别器状态,您将在模式视图控制器上调用您的方法。
是的,这是一个非常基本的版本。有人告诉我这很脆弱,但没有证据支持。
【参考方案1】:
嗯,这似乎可以在长按的同时处理轻按手势。还不错!
ViewController.swift
import UIKit
class ViewController: UIViewController, UIGestureRecognizerDelegate
var buttonView:UIView!
var longPressRecognizer:UILongPressGestureRecognizer?
override func viewDidLoad()
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// Add a button
buttonView = UIView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: 100))
buttonView.userInteractionEnabled = true;
buttonView.backgroundColor = UIColor.grayColor()
self.view.addSubview(buttonView)
override func viewDidAppear(animated: Bool)
if let recognizer = self.longPressRecognizer
// Reuse existing recognizer
self.longPressRecognizer = recognizer
recognizer.removeTarget(nil, action: nil)
recognizer.addTarget(self, action: "longPressed:")
recognizer.delegate = self
self.view.addGestureRecognizer(recognizer)
else
// Create a new new recognizer
self.longPressRecognizer = UILongPressGestureRecognizer(target: self, action: "longPressed:")
self.longPressRecognizer!.delegate = self
self.view.addGestureRecognizer(self.longPressRecognizer!)
override func viewDidDisappear(animated: Bool)
// Remove the recognizer
if let recognizer = self.longPressRecognizer
self.view.removeGestureRecognizer(recognizer)
func longPressed(recognizer: UILongPressGestureRecognizer)
let point: CGPoint = recognizer.locationInView(self.view)
if let pressedView = self.view.hitTest(point, withEvent: nil)
if pressedView == self.buttonView
switch recognizer.state
case .Began:
NSLog("ViewController: long pressed - Began")
var mediaViewController = MediaViewController()
mediaViewController.addRecognizer(recognizer)
self.presentViewController(mediaViewController, animated: false, completion: nil)
case .Cancelled:
NSLog("ViewController: long pressed - Cancelled")
case .Ended:
NSLog("ViewController: long pressed - Ended")
case .Changed:
NSLog("ViewController: long pressed - Changed")
default:
break
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
MediaViewController.swift
class MediaViewController: UIViewController, UIGestureRecognizerDelegate
var longPressRecognizer: UILongPressGestureRecognizer!
var tapRecognizer: UITapGestureRecognizer!
override func viewDidLoad()
super.viewDidLoad()
self.view.backgroundColor = UIColor.lightGrayColor()
self.tapRecognizer = UITapGestureRecognizer(target: self, action: "tap:")
self.tapRecognizer.cancelsTouchesInView = false
self.tapRecognizer.delegate = self
self.view.addGestureRecognizer(self.tapRecognizer)
self.longPressRecognizer.removeTarget(nil, action: nil)
self.longPressRecognizer.addTarget(self, action: "longPressed:")
self.longPressRecognizer.delegate = self
self.view.addGestureRecognizer(self.longPressRecognizer)
override func viewWillDisappear(animated: Bool)
// Remove gesture recognizers
self.view.removeGestureRecognizer(self.longPressRecognizer)
self.longPressRecognizer.delegate = nil
self.view.removeGestureRecognizer(self.tapRecognizer)
self.tapRecognizer.delegate = nil
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool
return true;
func longPressed(recognizer: UILongPressGestureRecognizer)
switch recognizer.state
case .Began:
NSLog("MediaViewController: long pressed - Began")
case .Cancelled:
NSLog("MediaViewController: long pressed - Cancelled")
case .Ended:
NSLog("MediaViewController: long pressed - Ended")
self.dismissViewControllerAnimated(false, completion: nil)
case .Changed:
NSLog("MediaViewController: long pressed - Changed")
default:
break
func tap(recongizer: UITapGestureRecognizer)
if (self.view.backgroundColor == UIColor.lightGrayColor())
self.view.backgroundColor = UIColor.greenColor()
else
self.view.backgroundColor = UIColor.lightGrayColor()
func addRecognizer(recognizer: UILongPressGestureRecognizer)
self.longPressRecognizer = recognizer
【讨论】:
谢谢!你拯救了我的一天!以上是关于将现有和活动的手势识别器传递给模态视图控制器的主要内容,如果未能解决你的问题,请参考以下文章
Swift 3使用选择器将按钮/手势识别器动作传递给其他功能