【问题标题】:Tapping on a video in a table view cell to open it in a view controller点击表格视图单元格中的视频以在视图控制器中打开它
【发布时间】:2021-05-13 17:19:46
【问题描述】:

tl;dr 我正在尝试在 Twitter 应用中重新创建它:https://i.imgur.com/173CVyM.mp4

如您所见,Twitter 在提要(表格视图单元格)中播放视频,当点击视频时,视频会平滑过渡到其自己的视图控制器,而不会停止或缓冲视频。

我已经完成了提要部分中的视频播放(在表格视图单元格中),但现在我被困在如何将视频平滑地转换为点击时的视图控制器。

在高层次上,我需要在这里做什么?

我当前的设置有一个AVPlayer 实例作为每个表格视图单元格的一部分。我会将AVPlayer 实例传递给视图控制器并继续从那里播放视频吗?内存管理呢?我觉得每个表格视图单元格都有一个AVPlayer 实例会导致一些问题,但我不完全确定。

作为第二个问题,如果我想忽略花哨的动画/过渡,当在表格视图单元格中点击视频时,如何继续在视图控制器中无缝播放视频?

【问题讨论】:

    标签: ios swift swift4 avplayer


    【解决方案1】:

    要从视频单元格转换到播放器控制器,您可以使用 AVPlayerLayer 和自定义动画,例如:

    ViewController.swift

    // Present player controller
    let playerViewController = AVPlayerViewController()
    playerViewController.player = player // Your current player instance
    playerViewController.transitioningDelegate = self // Custom animation
            
    self.present(playerViewController, animated: true, completion: nil)
    
    extension ViewController: UIViewControllerTransitioningDelegate {
      func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return PlayerAnimationController(playerLayer: playerLayer) // Your current player's layer
      }
    }
    

    PlayerAnimationController.swift

    class PlayerAnimationController: NSObject, UIViewControllerAnimatedTransitioning {
        
        let playerLayer: AVPlayerLayer
        
        init(playerLayer: AVPlayerLayer) {
            self.playerLayer = playerLayer
        }
        
        func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
            return 0.5
        }
        
        func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
            guard let toView = transitionContext.view(forKey: .to) else { return }
            
            let containerView = transitionContext.containerView
            containerView.addSubview(toView)
            
            let originalSuperlayer = playerLayer.superlayer
            let originalFrame = playerLayer.frame
            
            let frame = playerLayer.convert(playerLayer.bounds, to: nil)
            containerView.layer.addSublayer(self.playerLayer)
            
            // Start frame
            CATransaction.begin()
            CATransaction.setAnimationDuration(0)
            CATransaction.setDisableActions(true)
            
            self.playerLayer.frame = frame
            
            CATransaction.commit()
            
            toView.alpha = 0
            
            DispatchQueue.main.async {
                let duration = self.transitionDuration(using: transitionContext)
                UIView.animateKeyframes(withDuration: duration, delay: 0) {
                    UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 1/2) {
                        self.playerLayer.frame = containerView.bounds
                    }
                    
                    UIView.addKeyframe(withRelativeStartTime: 1/2, relativeDuration: 1/2) {
                        toView.alpha = 1.0
                    }
                }
                completion: { _ in
                    originalSuperlayer?.addSublayer(self.playerLayer)
                    self.playerLayer.frame = originalFrame
                    
                    transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
                }
            }
        }   
    }
    

    示例使用AVPlayerViewController,但您当然可以使用自己的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-13
      • 2012-12-03
      相关资源
      最近更新 更多