点击表格视图单元格中的视频以在视图控制器中打开它

Posted

技术标签:

【中文标题】点击表格视图单元格中的视频以在视图控制器中打开它【英文标题】: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 实例会导致一些问题,但我不完全确定。

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

【问题讨论】:

【参考方案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,但您当然可以使用自己的。

【讨论】:

以上是关于点击表格视图单元格中的视频以在视图控制器中打开它的主要内容,如果未能解决你的问题,请参考以下文章

如何使用自定义表格视图单元格中识别的点击手势从 UILabel 呈现视图控制器?

Obj-C - 点击自定义表格视图单元格中的删除表格视图行按钮

表格视图单元格中的集合视图

自定义表格视图单元格中的 UITextField。点击单元格/文本字段时显示选择器视图

Swift 表格视图,在表格视图单元格中播放视频,内存泄漏

如何使用自动布局来调整表格视图单元格中的视图大小?