Как я могу добавить жест смахивания к AVPlayer в Swift 3

Я использую Swift 3 и хочу добавить жест AVPlayer, Кто-то сказал мне, что для того, чтобы сделать это, я должен использовать другой вид и перенести этот вид в начало видео - так я и сделал, и вот мой код: (но не сработал):(

import UIKit
import AVKit
import AVFoundation

class ViewController: UIViewController , UIAlertViewDelegate {

let myFirstButton = UIButton()
let mySecondButton = UIButton()
var scoreLabel = UILabel()
var Player = AVPlayer()
var swipeGesture = UIGestureRecognizer()
var sView = UIView()


override func viewDidLoad() {
    super.viewDidLoad()


    ////////////
    sView.frame = self.view.frame
    self.view.addSubview(sView)
    self.view.bringSubview(toFront: sView)


    //////Swipe Gesture

    let swipeRight = UISwipeGestureRecognizer(target: sView, action: #selector(self.respondToSwipeGesture))
    swipeRight.direction = UISwipeGestureRecognizerDirection.right
    self.sView.addGestureRecognizer(swipeRight)

    let swipeLeft = UISwipeGestureRecognizer(target: sView, action: #selector(self.respondToSwipeGesture))
    swipeLeft.direction = UISwipeGestureRecognizerDirection.left
    self.sView.addGestureRecognizer(swipeLeft)

    let swipeUp = UISwipeGestureRecognizer(target: sView, action: #selector(self.respondToSwipeGesture))
    swipeUp.direction = UISwipeGestureRecognizerDirection.up
    self.sView.addGestureRecognizer(swipeUp)

    let swipeCustom = UISwipeGestureRecognizer(target: sView, action: #selector(self.respondToSwipeGesture))
    swipeCustom.direction = UISwipeGestureRecognizerDirection.init(rawValue: 200)
    self.sView.addGestureRecognizer(swipeCustom)


    let swipeDown = UISwipeGestureRecognizer(target: sView, action: #selector(self.respondToSwipeGesture))
    swipeDown.direction = UISwipeGestureRecognizerDirection.down
    self.sView.addGestureRecognizer(swipeDown)


    //////////////////////End Swipe Gesture

    let currentPlayerItem = Player.currentItem
    let duration = currentPlayerItem?.asset.duration
    let currentTime = Float(self.Player.currentTime().value)


        if currentTime >= 5 {

            print("OK")

        }else if currentTime <= 5 {

            print("NO")
        }

    NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: self.Player.currentItem, queue: nil, using: { (_) in
        DispatchQueue.main.async {
            self.Player.seek(to: kCMTimeZero)
            self.Player.play()
        }
    })



    /////////////
    NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: self.Player.currentItem, queue: nil, using: { (_) in
        DispatchQueue.main.async {
            self.Player.seek(to: kCMTimeZero)
            self.Player.play()
            DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 5.0) {
                // check if player is still playing
                if self.Player.rate != 0 {
                    print("OK")
                    print("Player reached 5 seconds")
                }
            }
        }
    })

}


fileprivate var firstAppear = true
//////Swipe Gesture 
func respondToSwipeGesture(gesture: UIGestureRecognizer) {
    if let swipeGesture = gesture as? UISwipeGestureRecognizer {
        switch swipeGesture.direction {
        case UISwipeGestureRecognizerDirection.right:
            print("Swiped right")
        case UISwipeGestureRecognizerDirection.down:
            print("Swiped down")
        case UISwipeGestureRecognizerDirection.left:
            print("Swiped left")
        case UISwipeGestureRecognizerDirection.up:
            print("Swiped up")
        case UISwipeGestureRecognizerDirection.init(rawValue: 200):
            print("Swiped Custom")

        default:
            break
        }
    }
}    
/////////End Swipe Gesture
override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    let value = UIInterfaceOrientation.landscapeLeft.rawValue
    UIDevice.current.setValue(value, forKey: "orientation")
    if firstAppear {
        do {
            try playBackgroundMovieVideo()
            firstAppear = false
        } catch AppError.invalidResource(let NMNF6327, let m4v) {
            debugPrint("Could not find resource \(NMNF6327).\(m4v)")
        } catch {
            debugPrint("Generic error")
        }


    }
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask{
    return UIInterfaceOrientationMask.landscapeLeft
}
fileprivate func playBackgroundMovieVideo() throws {
    guard let path = Bundle.main.path(forResource: "NMNF6327", ofType:"m4v") else {
        throw AppError.invalidResource("NMNF6327", "m4v")

    }

    self.Player = AVPlayer(url: URL(fileURLWithPath: path))
    let playerController = AVPlayerViewController()
    playerController.showsPlaybackControls = false
    playerController.view.isUserInteractionEnabled = true
    playerController.player = self.Player
    playerController.viewWillLayoutSubviews()
    playerController.allowsPictureInPicturePlayback = false



    myFirstButton.setImage(#imageLiteral(resourceName: "pause.png"), for: UIControlState.normal)
    myFirstButton.frame = CGRect(x: 5, y: 5, width: 70, height: 50)
    self.myFirstButton.addTarget(self, action:#selector(self.myFirstButtonpressed), for: .touchUpInside)
    self.view.addSubview(myFirstButton)

    playerController.view.addSubview(myFirstButton)

    mySecondButton.setImage(#imageLiteral(resourceName: "Options.png"), for: UIControlState.normal)
    mySecondButton.frame = CGRect(x: 60, y: 5, width: 70, height: 50)
    self.mySecondButton.addTarget(self, action:#selector(self.mySecondButtonClicked), for: .touchUpInside)
    self.view.addSubview(mySecondButton)

    playerController.view.addSubview(mySecondButton)


    self.present(playerController, animated: false) {
        self.Player.play()
    }
}

func playerDidReachEnd(notification: NSNotification) {
    self.Player.seek(to: kCMTimeZero)
    self.Player.play()
}

func myFirstButtonpressed(sender: UIButton!) {
    myFirstButton.setImage(#imageLiteral(resourceName: "Play.png"), for: UIControlState.normal)

    let alertView = UIAlertView();
    alertView.addButton(withTitle: "Continue");
    alertView.delegate=self;
    alertView.addButton(withTitle: "restart");
    alertView.addButton(withTitle: "Middle");
    alertView.title = "PAUSE";
    alertView.message = "";
    alertView.show();

    let playerController = AVPlayerViewController()
    playerController.viewWillLayoutSubviews()
    self.present(playerController , animated: true)
    self.Player.pause()

}

func mySecondButtonClicked(){

}





func alertView(_ alertView: UIAlertView, clickedButtonAt buttonIndex: Int) {


    if buttonIndex == 0
{

    self.Player.play()
    myFirstButton.setImage(#imageLiteral(resourceName: "pause.png"), for: UIControlState.normal)
    print("Continue")


}

    else if buttonIndex == 1 {
    self.Player.seek(to: kCMTimeZero)
     self.Player.play()
     myFirstButton.setImage(#imageLiteral(resourceName: "pause.png"), for: UIControlState.normal)


    }
    ////Middle
else if buttonIndex == 2 {
    myFirstButton.setImage(#imageLiteral(resourceName: "pause.png"), for: UIControlState.normal)
    let timeScale = self.Player.currentItem?.asset.duration.timescale;
    let time = CMTimeMakeWithSeconds( +9 , timeScale!)
    self.Player.seek(to: time, toleranceBefore: kCMTimeZero, toleranceAfter: kCMTimeZero)
    self.Player.play()
    }

}

override var shouldAutorotate: Bool{
    return false
}
func update() {
    myFirstButton.isHidden=false
}

}


enum AppError : Error {
case invalidResource(String, String)
    }

3 ответа

Решение

В вашем коде есть две ошибки.

1. Добавление вида жестов к неправильному виду контроллера. Вместо добавления представления жестов к AVPlayerViewController() вы добавляли исходный контроллер, который будет представлен функцией AVPlayerViewController() после представления.

3. Неправильная цель селектора Вы делали ложное предположение о цели на let swipeRight = UISwipeGestureRecognizer(target: sView, action: #selector(self.respondToSwipeGesture)), Вы устанавливали цель для sView и реализовывали метод селектора в ViewController.

Здесь цель означает целевой объект для метода селектора. Таким образом, изменение цели на себя (т. Е. Ваш контроллер представления) сделает ваш контроллер представления целью для метода выбора. func respondToSwipeGesture(gesture: UIGestureRecognizer)

пожалуйста, обратитесь к следующему исправленному коду.

import UIKit
import AVKit
import AVFoundation

class ViewController: UIViewController , UIAlertViewDelegate {

let myFirstButton = UIButton()
let mySecondButton = UIButton()
var scoreLabel = UILabel()
var Player = AVPlayer()
var swipeGesture = UIGestureRecognizer()
var sView = UIView()


override func viewDidLoad() {
    super.viewDidLoad()


    let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(self.respondToSwipeGesture))
    swipeRight.direction = UISwipeGestureRecognizerDirection.right
    self.sView.addGestureRecognizer(swipeRight)

    let swipeLeft = UISwipeGestureRecognizer(target: self, action: #selector(self.respondToSwipeGesture))
    swipeLeft.direction = UISwipeGestureRecognizerDirection.left
    self.sView.addGestureRecognizer(swipeLeft)

    let swipeUp = UISwipeGestureRecognizer(target: self, action: #selector(self.respondToSwipeGesture))
    swipeUp.direction = UISwipeGestureRecognizerDirection.up
    self.sView.addGestureRecognizer(swipeUp)

    let swipeCustom = UISwipeGestureRecognizer(target: self, action: #selector(self.respondToSwipeGesture))
    swipeCustom.direction = UISwipeGestureRecognizerDirection.init(rawValue: 200)
    self.sView.addGestureRecognizer(swipeCustom)


    let swipeDown = UISwipeGestureRecognizer(target: self, action: #selector(self.respondToSwipeGesture))
    swipeDown.direction = UISwipeGestureRecognizerDirection.down
    self.sView.addGestureRecognizer(swipeDown)


    //////////////////////End Swipe Gesture

    let currentPlayerItem = Player.currentItem
    let duration = currentPlayerItem?.asset.duration
    let currentTime = Float(self.Player.currentTime().value)


    if currentTime >= 5 {

        print("OK")

    }else if currentTime <= 5 {

        print("NO")
    }

    NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: self.Player.currentItem, queue: nil, using: { (_) in
        DispatchQueue.main.async {
            self.Player.seek(to: kCMTimeZero)
            self.Player.play()
        }
    })



    /////////////
    NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: self.Player.currentItem, queue: nil, using: { (_) in
        DispatchQueue.main.async {
            self.Player.seek(to: kCMTimeZero)
            self.Player.play()
            DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 5.0) {
                // check if player is still playing
                if self.Player.rate != 0 {
                    print("OK")
                    print("Player reached 5 seconds")
                }
            }
        }
    })

}


fileprivate var firstAppear = true
//////Swipe Gesture
func respondToSwipeGesture(gesture: UIGestureRecognizer) {
    if let swipeGesture = gesture as? UISwipeGestureRecognizer {
        switch swipeGesture.direction {
        case UISwipeGestureRecognizerDirection.right:
            print("Swiped right")
        case UISwipeGestureRecognizerDirection.down:
            print("Swiped down")
        case UISwipeGestureRecognizerDirection.left:
            print("Swiped left")
        case UISwipeGestureRecognizerDirection.up:
            print("Swiped up")
        case UISwipeGestureRecognizerDirection.init(rawValue: 200):
            print("Swiped Custom")

        default:
            break
        }
    }
}
/////////End Swipe Gesture
override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    let value = UIInterfaceOrientation.landscapeLeft.rawValue
    UIDevice.current.setValue(value, forKey: "orientation")
    if firstAppear {
        do {
            try playBackgroundMovieVideo()
            firstAppear = false
        } catch AppError.invalidResource(let NMNF6327, let m4v) {
            debugPrint("Could not find resource \(NMNF6327).\(m4v)")
        } catch {
            debugPrint("Generic error")
        }


    }
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask{
    return UIInterfaceOrientationMask.landscapeLeft
}
fileprivate func playBackgroundMovieVideo() throws {
    guard let path = Bundle.main.path(forResource: "NMNF6327", ofType:"m4v") else {
        throw AppError.invalidResource("NMNF6327", "m4v")

    }

    self.Player = AVPlayer(url: URL(fileURLWithPath: path))
    let playerController = AVPlayerViewController()
    playerController.showsPlaybackControls = false
    playerController.view.isUserInteractionEnabled = true
    playerController.player = self.Player
    playerController.viewWillLayoutSubviews()
    playerController.allowsPictureInPicturePlayback = false



    myFirstButton.setImage(#imageLiteral(resourceName: "pause.png"), for: UIControlState.normal)
    myFirstButton.frame = CGRect(x: 5, y: 5, width: 70, height: 50)
    self.myFirstButton.addTarget(self, action:#selector(self.myFirstButtonpressed), for: .touchUpInside)
    self.view.addSubview(myFirstButton)


    mySecondButton.setImage(#imageLiteral(resourceName: "Options.png"), for: UIControlState.normal)
    mySecondButton.frame = CGRect(x: 60, y: 5, width: 70, height: 50)
    self.mySecondButton.addTarget(self, action:#selector(self.mySecondButtonClicked), for: .touchUpInside)
    self.view.addSubview(mySecondButton)


    sView.frame = self.view.frame
    playerController.view.addSubview(sView)
    playerController.view.bringSubview(toFront: sView)

    // ****** buttons are added after sview ********** 
    playerController.view.addSubview(myFirstButton)

    playerController.view.addSubview(mySecondButton)

    self.present(playerController, animated: false) {
        self.Player.play()
    }
}

func playerDidReachEnd(notification: NSNotification) {
    self.Player.seek(to: kCMTimeZero)
    self.Player.play()
}

func myFirstButtonpressed(sender: UIButton!) {
    myFirstButton.setImage(#imageLiteral(resourceName: "Play.png"), for: UIControlState.normal)

    let alertView = UIAlertView();
    alertView.addButton(withTitle: "Continue");
    alertView.delegate=self;
    alertView.addButton(withTitle: "restart");
    alertView.addButton(withTitle: "Middle");
    alertView.title = "PAUSE";
    alertView.message = "";
    alertView.show();

    let playerController = AVPlayerViewController()
    playerController.viewWillLayoutSubviews()
    self.present(playerController , animated: true)
    self.Player.pause()

}

func mySecondButtonClicked(){

}





func alertView(_ alertView: UIAlertView, clickedButtonAt buttonIndex: Int) {


    if buttonIndex == 0
    {

        self.Player.play()
        myFirstButton.setImage(#imageLiteral(resourceName: "pause.png"), for: UIControlState.normal)
        print("Continue")


    }

    else if buttonIndex == 1 {
        self.Player.seek(to: kCMTimeZero)
        self.Player.play()
        //myFirstButton.setImage(#imageLiteral(resourceName: "pause.png"), for: UIControlState.normal)


    }
        ////Middle
    else if buttonIndex == 2 {
       myFirstButton.setImage(#imageLiteral(resourceName: "pause.png"), for: UIControlState.normal)
        let timeScale = self.Player.currentItem?.asset.duration.timescale;
        let time = CMTimeMakeWithSeconds( +9 , timeScale!)
        self.Player.seek(to: time, toleranceBefore: kCMTimeZero, toleranceAfter: kCMTimeZero)
        self.Player.play()
    }

}

override var shouldAutorotate: Bool{
    return false
}
func update() {
    myFirstButton.isHidden=false
}

 }


enum AppError : Error {
case invalidResource(String, String)
}

Swift 4

Вы можете сделать это без sView, просто добавьте распознаватель жестов в представление AVPlayerViewController:

func playVideo() {
    let playerController = AVPlayerViewController()
    playerController.player = AVPlayer(url: URL(fileURLWithPath: videoPath))
    playerController.showsPlaybackControls = false
    playerController.view.isUserInteractionEnabled = true

    let swipeUp = UISwipeGestureRecognizer(target: self, action: #selector(self.respondToSwipeGesture))
    swipeUp.direction = UISwipeGestureRecognizerDirection.up
    playerController.view.addGestureRecognizer(swipeUp)

    present(playerController, animated: false) {
        playerController.player?.play()
    }
}

@objc func respondToSwipeGesture(gesture: UIGestureRecognizer) {
    print("swipe up")
}

Возможно, вам нужно правильно инициализировать sView. Убедитесь, что вы присвоили необходимый кадр sView и добавили его в self.view как подпредставление.

override func viewDidLoad() {
    super.viewDidLoad()

    sView.frame = self.view.frame
    self.view.addSubview(sView)
    self.view.bringSubview(toFront: sView)

    // add you gestures to sView here ...
}

Вы должны сделать это:playerController.view.addSubview(self.sView) вместо self.view.addSubview(sView)

И вы должны добавить себя как tagart так:let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(respondToSwipeGesture))

Это будет работать. Это моя консоль:

Другие вопросы по тегам