Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/magento/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 在AVPlayerViewController中隐藏控件--仅在开始时_Ios_Video_Avplayer - Fatal编程技术网

Ios 在AVPlayerViewController中隐藏控件--仅在开始时

Ios 在AVPlayerViewController中隐藏控件--仅在开始时,ios,video,avplayer,Ios,Video,Avplayer,如果将avplayervewcontroller.showsPlaybackControls设置为false,则这些控件将根本不显示。即使你点击屏幕 我希望控件一开始是隐藏的,但仍然能够通过点击来召唤它们。如果我将提到的属性设置为true,则它们开始可见。(是的,它们会在几秒钟后褪色。)有没有办法开始隐藏,但仍然可以访问?更新:我最终制作了自己的控件,以实现更好的自定义。这更难,但值得花时间。请阅读苹果的示例代码以供参考。这是关于实现PiP的,也是关于制作自定义控件的: 更新:点击时,AvPl

如果将avplayervewcontroller.showsPlaybackControls设置为false,则这些控件将根本不显示。即使你点击屏幕


我希望控件一开始是隐藏的,但仍然能够通过点击来召唤它们。如果我将提到的属性设置为true,则它们开始可见。(是的,它们会在几秒钟后褪色。)有没有办法开始隐藏,但仍然可以访问?

更新:我最终制作了自己的控件,以实现更好的自定义。这更难,但值得花时间。请阅读苹果的示例代码以供参考。这是关于实现PiP的,也是关于制作自定义控件的:


更新:点击时,AvPlayServiceWController仅触发TouchesBegind事件,而不触发touchesEnded事件。但这足以显示控件

首先,您需要隐藏控件。在演示AVPlayerViewController之前,请先编写此代码

YourAVPlayerViewController.showsPlaybackControls = false
然后子类化AVPlayerViewController并添加此函数:

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {

    self.showsPlaybackControls = true

    super.touchesBegan(touches, withEvent: event)
}
当需要隐藏控件时,请执行以下操作:

var AVViewController = CustomAVPlayerViewController()

...

// Hide controls
AVViewController.showsPlaybackControls = false
// Show topView
AVViewController.topView.hidden = false

与会者的回答是好的。我会覆盖touchscancelled,这样控件就不会显示,然后再次隐藏

override public func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
    super.touchesCancelled(touches, withEvent: event)

    // toggle the player controls on if they were set to off
    if !self.showsPlaybackControls {
        self.showsPlaybackControls = true
    }
}
override public func touchscancelled(touchs:Set?,withEvent:UIEvent?){
super.touchscancelled(touchs,withEvent:event)
//如果播放器控件设置为关闭,则将其切换为打开
if!self.showsPlaybackControls{
self.showsPlaybackControls=true
}
}

我想我已经用动态手势识别器关系解决了这个问题。该解决方案避免了自定义控件(为了一致性),只使用公共API,并且不子类化
avplayervewcontroller
(如其他答案中所述,这是明确禁止的)

以下是方法:

  • 制作一个嵌入
    avplayervewcontroller
    的容器视图控制器。(无论控件如何,这都很有用,因为您需要将播放逻辑放在某个位置。)

  • 最初将
    showsPlaybackControls
    设置为
    false

  • 添加UITapgestureRecognitor以识别初始点击

  • 在手势识别器的动作方法中,将
    showsPlaybackControls
    设置为
    true

  • 到目前为止,它还可以工作,但在第一次点击时,控制会立即消失。若要解决此问题,请将自己设置为手势识别器的代理,实现手势识别器的
    gesturecognizer:should required of ailbygesturecognizer:
    ,并为任何其他单点击手势识别器返回
    true

  • 以下是Swift中的实际实现;检查回购以获取最新代码:

    import UIKit
    import AVKit
    import AVFoundation
    
    public class ModalMoviePlayerViewController: UIViewController {
    
        private let fileName: String
        private let loop: Bool
    
        private var item: AVPlayerItem!
        private var player: AVPlayer!
        internal private(set) var playerVC: AVPlayerViewController!
        private var waitingToAutostart = true
    
        public init(fileName: String, loop: Bool = true) {
            self.fileName = fileName
            self.loop = loop
            super.init(nibName: nil, bundle: nil)
        }
    
        public required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    
        public override func viewDidLoad() {
            super.viewDidLoad()
    
            let url = NSBundle.mainBundle().URLForResource(fileName, withExtension: nil)!
    
            item = AVPlayerItem(URL: url)
    
            player = AVPlayer(playerItem: item)
            player.actionAtItemEnd = .None
            player.addObserver(self, forKeyPath: "status", options: [], context: nil)
    
            NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ModalMoviePlayerViewController.didPlayToEndTime), name: AVPlayerItemDidPlayToEndTimeNotification, object: item)
    
            playerVC = AVPlayerViewController()
            playerVC.player = player
            playerVC.videoGravity = AVLayerVideoGravityResizeAspectFill
            playerVC.showsPlaybackControls = false
    
            let playerView = playerVC.view
            addChildViewController(playerVC)
            view.addSubview(playerView)
            playerView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
            playerView.frame = view.bounds
            playerVC.didMoveToParentViewController(self)
    
            let tapGesture = UITapGestureRecognizer(target: self, action: #selector(ModalMoviePlayerViewController.handleTap))
            tapGesture.delegate = self
            view.addGestureRecognizer(tapGesture)
        }
    
        deinit {
            player.pause()
            player.removeObserver(self, forKeyPath: "status")
            NSNotificationCenter.defaultCenter().removeObserver(self)
        }
    
        func togglePlayPause() {
            if isPlaying {
                pause()
            } else {
                play()
            }
        }
    
        func restart() {
            seekToStart()
            play()
        }
    
        func play() {
            if player.status == .ReadyToPlay {
                player.play()
            } else {
                waitingToAutostart = true
            }
        }
    
        func pause() {
            player.pause()
            waitingToAutostart = false
        }
    
        var isPlaying: Bool {
            return (player.rate > 1 - 1e-6) || waitingToAutostart
        }
    
        private func performStateTransitions() {
            if waitingToAutostart && player.status == .ReadyToPlay {
                player.play()
            }
        }
    
        public override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
            performStateTransitions()
        }
    
        @objc func didPlayToEndTime() {
            if isPlaying && loop {
                seekToStart()
            }
        }
    
        private func seekToStart() {
            player.seekToTime(CMTimeMake(0, 10))
        }
    
        public override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
            if !playerVC.showsPlaybackControls {
                playerVC.showsPlaybackControls = true
            }
            super.touchesBegan(touches, withEvent: event)
        }
    
    }
    
    extension ModalMoviePlayerViewController: UIGestureRecognizerDelegate {
    
        @IBAction func handleTap(sender: UIGestureRecognizer) {
            if !playerVC.showsPlaybackControls {
                playerVC.showsPlaybackControls = true
            }
        }
    
        /// Prevents delivery of touch gestures to AVPlayerViewController's gesture recognizer,
        /// which would cause controls to hide immediately after being shown.
        ///
        /// `-[AVPlayerViewController _handleSingleTapGesture] goes like this:
        ///
        ///     if self._showsPlaybackControlsView() {
        ///         _hidePlaybackControlsViewIfPossibleUntilFurtherUserInteraction()
        ///     } else {
        ///         _showPlaybackControlsViewIfNeededAndHideIfPossibleAfterDelayIfPlaying()
        ///     }
        public func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailByGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
            if !playerVC.showsPlaybackControls {
                // print("\nshouldBeRequiredToFailByGestureRecognizer? \(otherGestureRecognizer)")
                if let tapGesture = otherGestureRecognizer as? UITapGestureRecognizer {
                    if tapGesture.numberOfTouchesRequired == 1 {
                        return true
                    }
                }
            }
            return false
        }
    
    }
    
    导入UIKit
    进口AVKit
    进口AVF基金会
    公共类ModalMoviePlayerViewController:UIViewController{
    私有let文件名:String
    私有let循环:Bool
    私有变量项:AVPlayerItem!
    私人玩家:AVPlayer!
    内部专用(设置)var playerVC:AVPlayerViewController!
    private var waitingtooutostart=true
    public init(文件名:String,循环:Bool=true){
    self.fileName=文件名
    self.loop=循环
    super.init(nibName:nil,bundle:nil)
    }
    公共必需的初始化?(编码者aDecoder:NSCoder){
    fatalError(“初始化(编码者:)尚未实现”)
    }
    公共覆盖函数viewDidLoad(){
    super.viewDidLoad()
    让url=NSBundle.mainBundle().URLForResource(文件名,扩展名:nil)!
    item=AVPlayerItem(URL:URL)
    player=AVPlayer(playerItem:item)
    player.actionAtItemEnd=.None
    addObserver(self,forKeyPath:“状态”,选项:[],上下文:nil)
    NSNotificationCenter.defaultCenter().addObserver(self,选择器:#选择器(ModalMoviePlayerViewController.didPlayToEndTime),名称:avPlayerItemDidPlaytoEndTime通知,对象:item)
    playerVC=avplayervewcontroller()
    playerVC.player=玩家
    playerVC.videoGravity=AVLayerVideoGravityResizeAspectFill
    playerVC.showsPlaybackControls=false
    让playerView=playerVC.view
    addChildViewController(playerVC)
    view.addSubview(playerView)
    playerView.autoresizingMask=[.FlexibleWidth、.FlexibleHeight]
    playerView.frame=view.bounds
    playerVC.didMoveToParentViewController(自身)
    让Tap手势=UITapGestureRecognitor(目标:自我,操作:#选择器(ModalMoviePlayerViewController.handleTap))
    tappostate.delegate=self
    view.AddGestureRecognitor(点击手势)
    }
    脱硝{
    player.pause()
    player.removeObserver(自我,分叉路径:“状态”)
    NSNotificationCenter.defaultCenter().removeObserver(自)
    }
    函数切换播放暂停(){
    如果显示{
    暂停()
    }否则{
    play()
    }
    }
    func restart(){
    seekToStart()
    play()
    }
    func play(){
    如果player.status==.ReadyToPlay{
    player.play()
    }否则{
    WaitingToutostart=true
    }
    }
    函数暂停(){
    player.pause()
    WaitingToutostart=false
    }
    变量显示:Bool{
    返回(player.rate>1-1e-6)| |等待开始
    }
    private func PerformStateTransformations(){
    如果waitingToAutostart&&player.status==.ReadyToPlay{
    player.play()
    }
    }
    public override func observeValueForKeyPath(键路径:String?,对象的类型:AnyObject?,更改:[String:AnyObject]?,上下文:UnsafeMutablePointer){
    PerformStateTransformations()
    }
    @objc func didPlayToEndTime(){
    如果isplay&循环{
    seekToStart()
    }
    }
    私有函数seekToStart(){
    播放器。seekToTime(CMTimeMake(0,10))
    }
    公共覆盖功能触摸开始(触摸:设置,withEvent事件:UIEvent?){
    如果!playerVC.showsPlaybackControls{
    playerVC.showsPlaybackControls=true
    }
    超级接触开始了
    
    import UIKit
    import AVKit
    import AVFoundation
    
    public class ModalMoviePlayerViewController: UIViewController {
    
        private let fileName: String
        private let loop: Bool
    
        private var item: AVPlayerItem!
        private var player: AVPlayer!
        internal private(set) var playerVC: AVPlayerViewController!
        private var waitingToAutostart = true
    
        public init(fileName: String, loop: Bool = true) {
            self.fileName = fileName
            self.loop = loop
            super.init(nibName: nil, bundle: nil)
        }
    
        public required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    
        public override func viewDidLoad() {
            super.viewDidLoad()
    
            let url = NSBundle.mainBundle().URLForResource(fileName, withExtension: nil)!
    
            item = AVPlayerItem(URL: url)
    
            player = AVPlayer(playerItem: item)
            player.actionAtItemEnd = .None
            player.addObserver(self, forKeyPath: "status", options: [], context: nil)
    
            NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ModalMoviePlayerViewController.didPlayToEndTime), name: AVPlayerItemDidPlayToEndTimeNotification, object: item)
    
            playerVC = AVPlayerViewController()
            playerVC.player = player
            playerVC.videoGravity = AVLayerVideoGravityResizeAspectFill
            playerVC.showsPlaybackControls = false
    
            let playerView = playerVC.view
            addChildViewController(playerVC)
            view.addSubview(playerView)
            playerView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
            playerView.frame = view.bounds
            playerVC.didMoveToParentViewController(self)
    
            let tapGesture = UITapGestureRecognizer(target: self, action: #selector(ModalMoviePlayerViewController.handleTap))
            tapGesture.delegate = self
            view.addGestureRecognizer(tapGesture)
        }
    
        deinit {
            player.pause()
            player.removeObserver(self, forKeyPath: "status")
            NSNotificationCenter.defaultCenter().removeObserver(self)
        }
    
        func togglePlayPause() {
            if isPlaying {
                pause()
            } else {
                play()
            }
        }
    
        func restart() {
            seekToStart()
            play()
        }
    
        func play() {
            if player.status == .ReadyToPlay {
                player.play()
            } else {
                waitingToAutostart = true
            }
        }
    
        func pause() {
            player.pause()
            waitingToAutostart = false
        }
    
        var isPlaying: Bool {
            return (player.rate > 1 - 1e-6) || waitingToAutostart
        }
    
        private func performStateTransitions() {
            if waitingToAutostart && player.status == .ReadyToPlay {
                player.play()
            }
        }
    
        public override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
            performStateTransitions()
        }
    
        @objc func didPlayToEndTime() {
            if isPlaying && loop {
                seekToStart()
            }
        }
    
        private func seekToStart() {
            player.seekToTime(CMTimeMake(0, 10))
        }
    
        public override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
            if !playerVC.showsPlaybackControls {
                playerVC.showsPlaybackControls = true
            }
            super.touchesBegan(touches, withEvent: event)
        }
    
    }
    
    extension ModalMoviePlayerViewController: UIGestureRecognizerDelegate {
    
        @IBAction func handleTap(sender: UIGestureRecognizer) {
            if !playerVC.showsPlaybackControls {
                playerVC.showsPlaybackControls = true
            }
        }
    
        /// Prevents delivery of touch gestures to AVPlayerViewController's gesture recognizer,
        /// which would cause controls to hide immediately after being shown.
        ///
        /// `-[AVPlayerViewController _handleSingleTapGesture] goes like this:
        ///
        ///     if self._showsPlaybackControlsView() {
        ///         _hidePlaybackControlsViewIfPossibleUntilFurtherUserInteraction()
        ///     } else {
        ///         _showPlaybackControlsViewIfNeededAndHideIfPossibleAfterDelayIfPlaying()
        ///     }
        public func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailByGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
            if !playerVC.showsPlaybackControls {
                // print("\nshouldBeRequiredToFailByGestureRecognizer? \(otherGestureRecognizer)")
                if let tapGesture = otherGestureRecognizer as? UITapGestureRecognizer {
                    if tapGesture.numberOfTouchesRequired == 1 {
                        return true
                    }
                }
            }
            return false
        }
    
    }
    
    @IBAction func enableControls(button:UIButton)
    {
        controller?.showsPlaybackControls = true
        button.isHidden = true //The button is only needed once, then the player takes over.
    }