繁体   English   中英

为CALayer设置动画

[英]animating a CALayer

我在UIView上有一个CALayer。

UIView的动画正是我想要它,但是这是在它之上的PlayerView似乎“重生”离屏幕动画,然后到了UIView中开始,然后它会以动画的UIViews帧中的位置。

我想知道是否有CALayers的任何属性可以自动处理此问题,但我什么都没找到。

这是此代码:

    let window = UIApplication.shared.keyWindow!
     v = UIView(frame: CGRect(x: window.frame.origin.x, y: window.frame.origin.y, width: window.frame.width, height: window.frame.height))
     let v2 = UIView(frame: .zero)
    window.addSubview(v!);
    window.addSubview(v2)
    v?.backgroundColor = UIColor.black
    v2.backgroundColor = UIColor.clear

    v?.layer.cornerRadius = (v?.frame.width)! * 0.025






    guard let path = Bundle.main.path(forResource: "video", ofType:"mp4") else {
        debugPrint("video.m4v not found")
        return
    }

    player = AVPlayer(url: URL(fileURLWithPath: path))

    playerLayer = AVPlayerLayer(player: player)
    //        playerLayer.frame = playerView.frame

    playerLayer?.frame = (playerView?.bounds)!
    playerLayer?.masksToBounds = true

    playerLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill


    v?.layer.addSublayer(playerLayer!)

    player?.play()
    player?.isMuted = true

    //looper
    NotificationCenter.default.addObserver(forName: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: player?.currentItem, queue: nil)
    { notification in
        let t1 = CMTimeMake(5, 100)
        self.player?.seek(to: t1)

        self.player?.play()
    }







    let superview = playerView?.superview

    v2.frame = (v2.convert((playerView?.frame)!, from: superview))
            v?.frame = (v?.convert((playerView?.frame)!, from: superview))!

    window.addConstraintsWithFormat("H:|[v0]|", views: v!)
    window.addConstraintsWithFormat("V:|[v0]|", views: v!)

            playerLayer?.frame = (v?.frame)!



                self.playerLayer?.frame = (self.v?.frame)!


    UIView.animate(withDuration: 4, delay: 0, options: UIViewAnimationOptions.curveEaseOut, animations: {



        self.window?.layoutIfNeeded()

    }, completion: { (completed) in


        self.playerLayer?.frame = (self.v?.frame)!



    })


}

有什么建议么?

编辑:

我已包含更新的代码

    let window = UIApplication.shared.keyWindow!
    v = UIView(frame: CGRect(x: window.frame.origin.x, y: window.frame.origin.y, width: window.frame.width, height: window.frame.height))
    let v2 = UIView(frame: .zero)
    window.addSubview(v!);

    v?.addSubview(playerView2!)

    window.addSubview(v2)
    v?.backgroundColor = UIColor.black
    v2.backgroundColor = UIColor.clear

    v?.layer.cornerRadius = (v?.frame.width)! * 0.025










    playerView2?.layer.cornerRadius = (playerView2?.bounds.width)! * 0.025

    guard let path = Bundle.main.path(forResource: "video", ofType:"mp4") else {
        debugPrint("video.m4v not found")
        return
    }

    player = AVPlayer(url: URL(fileURLWithPath: path))

    playerLayer = AVPlayerLayer(player: player)
    //        playerLayer.frame = playerView.frame

    playerLayer?.frame = (playerView2?.bounds)!
    playerLayer?.masksToBounds = true
    playerLayer?.cornerRadius = (playerView2?.bounds.width)! * 0.025

    playerLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill


    self.playerView2?.layer.addSublayer(playerLayer!)

//        player?.play()
    player?.isMuted = true

    //looper
    NotificationCenter.default.addObserver(forName: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: player?.currentItem, queue: nil)
    { notification in
        let t1 = CMTimeMake(5, 100)
        self.player?.seek(to: t1)

//            self.player?.play()
    }










    self.playerView2?.frame = (self.v?.bounds)!
    self.playerLayer?.frame = (self.playerView?.bounds)!





    UIView.animate(withDuration: 5, delay: 0, options: UIViewAnimationOptions.curveEaseOut, animations: {



        self.v?.frame = window.frame

        self.playerView2?.frame = (self.v?.frame)!

        self.playerLayer?.frame = (self.playerView2?.frame)!



        self.window?.layoutIfNeeded()

    }, completion: { (completed) in




    })





}

设置playerLayer.frame时,您将获得一个隐式动画。

如果您不想使用任何动画,请暂时禁用如下所示的隐式动画:

        UIView.animate(withDuration: 4, delay: 0, options: UIViewAnimationOptions.curveEaseOut, animations: {
            self.window?.layoutIfNeeded()
        }, completion: { (completed) in
            let priorValue = CATransaction.disableActions()
            CATransaction.setDisableActions(true)
            self.playerLayer?.frame = self.v!.frame
            CATransaction.setDisableActions(priorValue)
        })

如果您想为playerLayer.frame设置动画,那么最好的方法是创建一个使用AVPlayerLayer作为其图层的UIView子类,如下所示:

class PlayerView: UIView {
    override class var layerClass: AnyClass { return AVPlayerLayer.self }
    private(set) lazy var playerLayer: AVPlayerLayer = { self.layer as! AVPlayerLayer }()
}

然后,您可以使用PlayerView代替裸露的AVPlayerLayer并使用UIKit动画。 由于您无法直接初始化AVPlayerLayerUIView使用默认的初始化程序创建其图层),因此需要像这样设置PlayerView的播放器:

        playerView?.playerLayer = player

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM