【问题标题】:Animate video UIView to go full screen like YouTube App动画视频 UIView 像 YouTube 应用一样全屏显示
【发布时间】:2017-04-22 20:37:25
【问题描述】:

我有一个视图控制器,它有一个UIView,我称之为playerView。在playerView 中,我使用AVLayerAVPlayerLayer 向用户展示视频。当您第一次点击任何视频时,对 Youtube 应用进行映像。

我如何操纵这个playerView 的框架,让它占据整个屏幕。 (全屏)

这是当前帧:

 //16 x 9 is the aspect ratio of all HD videos
 let height = view.frame.width * 9 / 16
 let playerFrame = CGRect(x: 0, y: 0, width: view.frame.width, height: height)    
 playerView.frame = videoPlayerFrame

我在 YouTube 应用中进行了测试,他们的应用只支持纵向(就像我的一样),因为全屏视频的动画看起来如何。如何在点击按钮时甚至在用户水平握持设备时更进一步地做到这一点?

UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {

   self.playerView.frame = ?

}, completion: nil)

编辑:试过了,但它并没有真正按照我想要的方式工作......它不会占据整个屏幕

UIView.animate(withDuration: 0.8, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {

   self.playerView.frame = CGRect(x: 0, y: 0, width: self.view.frame.height, height: self.view.frame.width)
   self.playerView.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi / 2))

}, completion: nil)

【问题讨论】:

  • 您不应该为框架设置动画。动画转换,你会没事的
  • @Mannopson 感谢您的建议!你能展示一些示例代码吗?
  • 我指的是变换的比例而不是框架。
  • @Mannopson 你介意发布一些代码吗?我无法解读您的信息
  • 我会给你一个想法,但不是现在。好吗?

标签: swift animation uiview


【解决方案1】:

我想通了。

我创建了一个名为isExpanded 的全局变量,当我们处于全屏模式时,该变量将设置为true。另外,我创建了一个名为 videoPlayerViewCenter 的 CGPoint 变量,这样我就可以在全屏之前保存中心,以便在返回小屏幕时再次设置它。

这是当用户想要全屏时调用的代码

func fullScreenTapped(sender: vVideoPlayer) {

        if !isExpanded {
            //Expand the video
            UIView.animate(withDuration: 0.8, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {

                self.videoPlayerViewCenter = self.videoPlayerView.center

                self.videoPlayerView.frame = CGRect(x: 0, y: 0, width: self.view.frame.height, height: self.view.frame.width)
                self.videoPlayerView.center = self.view.center
                self.videoPlayerView.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi / 2))
                self.videoPlayerView.layoutSubviews()

            }, completion: nil)
        } else {
            //Shrink the video again

            UIView.animate(withDuration: 0.8, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {

                //16 x 9 is the aspect ratio of all HD videos

                self.videoPlayerView.transform = CGAffineTransform.identity
                self.videoPlayerView.center = self.videoPlayerViewCenter

                let height = self.view.frame.width * 9 / 16
                let videoPlayerFrame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: height)
                self.videoPlayerView.frame = videoPlayerFrame

                self.videoPlayerView.layoutSubviews()

            }, completion: nil)
        }

        isExpanded = !isExpanded
    }

为了展开视频,我将中心保存在全局 CGPoint 变量中,然后设置帧。然后,我设置中心并使用CGAffineTransform 旋转 90 度。

为了再次缩小视频,我基本上将设置设置为之前的设置。 (做事的顺序很重要)

另一件也很重要的事情是在你的 videoPlayerView 中覆盖你的 layoutSubviews 方法,如下所示:

override func layoutSubviews() {
        super.layoutSubviews()
        self.playerLayer?.frame = self.bounds
    }

这将使您的playerLayer 在视图变大时调整其框架。

【讨论】:

    【解决方案2】:

    我知道为时已晚,但也许其他人会发现此代码有帮助。

    我曾经在我的视图中使用自动布局约束,因此动画必须采用不同的方法。

    func setMapFullScreen(_ fullscreen: Bool) {
    
        if fullscreen {
            // Set the full screen constraints
            self.setFullScreenLayoutConstraints()
    
            // Hide the navigation bar
            self.navigationController?.setNavigationBarHidden(true, animated: true)
    
        } else {
            // Set small screen constraints
            self.setSmallScreenLayoutConstraints()
    
            // Show the navigation bar
            self.navigationController?.setNavigationBarHidden(false, animated: true)
        }
    
        // Animate to full screen
        UIView.animate(withDuration: 0.8, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
    
            self.view.layoutIfNeeded()
    
        }) { (finished) in
            // ...
        }
    

    在我的情况下,我有MKMapView,我想点击它以全屏(和返回)查看地图。 这是转换状态的函数。

    如您所见,在UIView.animate 调用中,我只为self.view.layoutIfNeeded() 设置动画

    我也隐藏了导航栏,因为我有一个 ☺

    这是我的setSmallScreenLayoutConstraintssetFullScreenLayoutConstraints 函数使用SnapKit 框架

    func setSmallScreenLayoutConstraints() {
        self.mapView.snp.remakeConstraints { (make) -> Void in
            make.top.equalTo(self.mapLabel.snp.bottom).offset(8)
            make.left.equalTo(self.view).offset(0)
            make.right.equalTo(self.view).offset(0)
            make.height.equalTo(150)
        }
    }
    
    func setFullScreenLayoutConstraints() {
        self.mapView.snp.remakeConstraints { (make) -> Void in
            make.top.equalTo(self.view).offset(0)
            make.left.equalTo(self.view).offset(0)
            make.right.equalTo(self.view).offset(0)
            make.bottom.equalTo(self.view).offset(0)
        }
    }
    

    这是结果

    享受!!

    【讨论】:

      【解决方案3】:

      正如我所说,这不是您问题的答案。这是一个想法,希望对您有所帮助:

       var rectangleView:UIView!
      
      override func viewDidLoad() {
          super.viewDidLoad()
      
          // Tap Gesture Recognizer for growing the rectangleView
          let tapForward = UITapGestureRecognizer.init(target: self, action: #selector(self.tapForward(tap:)))
          tapForward.numberOfTapsRequired = 1
      
      
          // Configure the rectangleView
          self.rectangleView = UIView.init(frame: CGRect.init(x: 0, y: 0, width: self.view.bounds.width, height: self.view.bounds.height))
          self.rectangleView.transform = CGAffineTransform.init(scaleX: 0.65, y: 0.25)
          self.rectangleView.backgroundColor = UIColor.red
          self.rectangleView.addGestureRecognizer(tapForward)
          self.view.addSubview(rectangleView)
      }
      

      这将是我们的tapForward(tap:) 函数:

      func tapForward(tap:UITapGestureRecognizer) {
      
          UIView.animate(withDuration: 0.5, delay: 0.0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.8, options: .curveEaseInOut, animations: {
      
              self.rectangleView.transform = CGAffineTransform.identity
      
          }) { (completed:Bool) in
              // Completion block
          }
      }
      

      【讨论】:

      • 谢谢@Mannopson。你能解释一下这是做什么的吗?
      • 所以我们创建了一个自定义的UIView,它的比例更小。只要点击它就会变成全屏模式
      • 这没有帮助。您只是将视图设置为全尺寸......缩小它......然后将其设置回原来的尺寸。如果您查看 youtube 的动画,则视图会翻转并占据整个景观区域。如果我会按照您的方式进行操作,我必须首先将视图设置为占据整个尺寸,然后以某种方式将其缩小以在看到原始 youtube 视频时显示.. 顶部很小.甚至不知道该怎么做....
      猜你喜欢
      • 2015-04-29
      • 1970-01-01
      • 2012-02-17
      • 1970-01-01
      • 1970-01-01
      • 2016-10-23
      • 1970-01-01
      • 2012-01-29
      • 2012-12-26
      相关资源
      最近更新 更多