2

I want to check if swipe gesture working or not on AVPlayer video. I tried a small sample app to do so but it did not work. Not sure why code is not working.

On button tap, below is the code:

var playerLayer: AVPlayerLayer?
var player: AVPlayer?

        let videoUrlString = "https://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"
        let videoURL = URL(string: videoUrlString)
        self.player = AVPlayer(url: videoURL!)
        let playerViewController = AVPlayerViewController()
        playerViewController.player = player
        present(playerViewController, animated: true, completion: {
            self.player?.play()
        })

        let leftSwipe = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipes(_:)))
        leftSwipe.direction = UISwipeGestureRecognizer.Direction.up

        playerViewController.view.addGestureRecognizer(leftSwipe)

@objc func handleSwipes(_ sender:UISwipeGestureRecognizer) {

        if (sender.direction == .left) {

            let alert = UIAlertController(title: "Swipe Action", message: "It is LEFT Swipe ", preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
            self.present(alert, animated: true
        }
   }

Thanks

Dharmesh Kheni
  • 71,228
  • 33
  • 160
  • 165
janubhai
  • 183
  • 1
  • 8

3 Answers3

1

First of you need to disable AVPlayerViewController's default gestureRecognizers for that you can use

extension AVPlayerViewController {
    func disableGestureRecognition() {
        let contentView = view.value(forKey: "contentView") as? UIView
        contentView?.gestureRecognizers = contentView?.gestureRecognizers?.filter { $0 is UITapGestureRecognizer }
    }
}

And you can use it like:

playerViewController.disableGestureRecognition()

Now you need to replace

leftSwipe.direction = UISwipeGestureRecognizer.Direction.up

with

leftSwipe.direction = UISwipeGestureRecognizer.Direction.left

because you are checking for left direction.

And since your UIViewController is not longer in window hierarchy you can not present alert with self.present and to solve that you need to make playerViewController as a global variable in your class.

and then you can present alert like:

playerViewController.present(alert, animated: true)

in your handleSwipes method.

And working code will be like:

import UIKit
import AVKit

class ViewController: UIViewController {

    var playerLayer: AVPlayerLayer?
    var player: AVPlayer?
    let playerViewController = AVPlayerViewController()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    @IBAction func tap(_ sender: Any) {

        let videoUrlString = "https://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"
        let videoURL = URL(string: videoUrlString)
        self.player = AVPlayer(url: videoURL!)

        playerViewController.player = player

        playerViewController.disableGestureRecognition()
        present(playerViewController, animated: true, completion: {
            self.player?.play()
        })

        let leftSwipe = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipes(_:)))
        leftSwipe.direction = UISwipeGestureRecognizer.Direction.left
        playerViewController.view.addGestureRecognizer(leftSwipe)
    }

    @objc func handleSwipes(_ sender:UISwipeGestureRecognizer) {

        if (sender.direction == .left) {

            let alert = UIAlertController(title: "Swipe Action", message: "It is LEFT Swipe ", preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
            playerViewController.present(alert, animated: true)
        }
    }
}

extension AVPlayerViewController {
    func disableGestureRecognition() {
        let contentView = view.value(forKey: "contentView") as? UIView
        contentView?.gestureRecognizers = contentView?.gestureRecognizers?.filter { $0 is UITapGestureRecognizer }
    }
}

And result will be:

enter image description here

Dharmesh Kheni
  • 71,228
  • 33
  • 160
  • 165
0

Did you enable the user interactions on your view?

playerViewController.view.isUserInteractionEnabled = true

I don't know the player but you should read the doc, maybe it already catches the swipe gestures and provides an API to use it.

Regards,

0

Try setting the delegate for UISwipeGestureRecognizer, i.e.

leftSwipe.delegate = self

And conform your viewController to UIGestureRecognizerDelegate

class ViewController: UIViewController, UIGestureRecognizerDelegate {
    //Rest of the code
}
PGDev
  • 23,751
  • 6
  • 34
  • 88