将现有和活动的手势识别器传递给模态视图控制器

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使用选择器将按钮/手势识别器动作传递给其他功能

如何在 MapView 上点击然后将其传递给默认手势识别器?

如何在iOS中将触摸传递给手势识别器?