Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing an existing and active gesture recognizer to a modal view controller

I want to launch a modal view with a long press, and then dismiss the modal view when the long press is cancelled. How do I do this?

  • I tried passing the longPressRecognizer to the modal view and setting it as a delegate, but that didn't work.
  • I tried something simpler- detecting a touchesEnded, which would mean in the modal view a touch ended, but that doesn't fire either.

Is there a way to tell the modal view a gesture has started; I want you to recognize the end/cancellation of this gesture or a touch?


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")
    }

}
like image 720
nflacco Avatar asked Apr 09 '15 17:04

nflacco


1 Answers

Hmmm, this appears to work and handle a tap gesture simultaneously with the long press. Not bad!


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
    }

}
like image 169
nflacco Avatar answered Oct 22 '22 22:10

nflacco