Swift : 为 CALayer 暂停 CABasicAnimation

Posted

技术标签:

【中文标题】Swift : 为 CALayer 暂停 CABasicAnimation【英文标题】:Swift : Pause CABasicAnimation for CALayer 【发布时间】:2016-01-12 04:39:54 【问题描述】:

您在下面看到的代码创建了一个 CALayer(矩形形状)并从左到右对其进行动画处理(您可以直接在新项目中复制和粘贴代码):

     //Global Variables
var layer = CALayer()
var holdGesture = UILongPressGestureRecognizer()
let animation = CABasicAnimation(keyPath: "bounds.size.width")


func setUpView()

    self.view.addGestureRecognizer(holdGesture)
    holdGesture.addTarget(self, action:"handleLongPress:")




func handleLongPress(sender : UILongPressGestureRecognizer)

    //NEED IT HERE
    //var layer = CALayer()

    layer.frame = CGRect(x: 0, y: 0, width: 0, height: 10)
    layer.backgroundColor = UIColor.redColor().CGColor

    animation.fromValue = 0
    animation.toValue = self.view.bounds.width * 2
    animation.duration = 5
    self.view.layer.addSublayer(layer)

    if(sender.state == .Began)
        print("Long Press Began")
        layer.addAnimation(animation, forKey: "bounds.size.width")
    


    else
        print("Long press ended")
        pauseLayer(layer)
    



func pauseLayer(layer : CALayer)
    let pausedTime : CFTimeInterval = layer.convertTime(CACurrentMediaTime(), fromLayer: nil)
    layer.speed = 0.0
    layer.timeOffset = pausedTime





override func didReceiveMemoryWarning()
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.

override func viewDidLoad() 
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    setUpView()


我遇到的问题是变量“layer”只能暂停(通过“pauseLayer”函数时)如果它是一个全局变量!我不知道为什么!我想在“handleLongPress”函数中声明变量。这是因为我需要在每次识别到 longPressGestureRecognizer 时声明一个具有相同名称的新变量。我试过用“inout”通过引用传递,但它似乎没有用。有人可以帮忙吗?请。

【问题讨论】:

【参考方案1】:

暂停层

func pauseLayer(layer : CALayer)
    let pausedTime : CFTimeInterval = layer.convertTime(CACurrentMediaTime(), from: nil)
    layer.speed = 0.0
    layer.timeOffset = pausedTime


我还给你恢复功能:D

func resumeAnimation(layer : CALayer)
    let pausedTime = layer.timeOffset
    layer.speed = 1.0
    layer.timeOffset = 0.0
    layer.beginTime = 0.0
    let timeSincePause = layer.convertTime(CACurrentMediaTime(), from: nil) - pausedTime
    layer.beginTime = timeSincePause

【讨论】:

优秀的解决方案。派上用场了。【参考方案2】:

使用这个修改后的代码:

//Global Variables
var layer: CALayer?
var holdGesture = UILongPressGestureRecognizer()
let animation = CABasicAnimation(keyPath: "bounds.size.width")


func setUpView()

    self.view.addGestureRecognizer(holdGesture)
    holdGesture.addTarget(self, action:"handleLongPress:")




func handleLongPress(sender : UILongPressGestureRecognizer)

    if(sender.state == .Began) 

        let newLayer = CALayer()
        newLayer.frame = CGRect(x: 0, y: 0, width: 0, height: 10)
        newLayer.backgroundColor = UIColor.redColor().CGColor

        animation.fromValue = 0
        animation.toValue = self.view.bounds.width * 2
        animation.duration = 5
        self.view.layer.addSublayer(newLayer)

        print("Long Press Began")
        newLayer.addAnimation(animation, forKey: "bounds.size.width")

        layer = newLayer
    
    else 
        print("Long press ended")

        if let layer = layer 
            pauseLayer(layer)
            layer.removeFromSuperlayer()
        
    



func pauseLayer(layer : CALayer)
    let pausedTime : CFTimeInterval = layer.convertTime(CACurrentMediaTime(), fromLayer: nil)
    layer.speed = 0.0
    layer.timeOffset = pausedTime


【讨论】:

你太棒了,我的好先生! 我的好先生,您知道如何跟踪图层的宽度吗?我尝试“layer.bounds.size.width”来打印图层的宽度,但它总是返回 0。有什么想法吗? newLayer.frame = CGRect(x: 0, y: 0, width: 0, height: 10) 在这里给出适当的宽度。 没错!但是当“长按结束”时,如果你打印“层”的宽度,它会打印出0。我不太清楚为什么。 使用:layer.presentationLayer()?.bounds.width

以上是关于Swift : 为 CALayer 暂停 CABasicAnimation的主要内容,如果未能解决你的问题,请参考以下文章

使用 Swift3 子类化 CALayer + 隐式动画

Swift:如何为 CALayer 启用捏合缩放功能?

在 Swift 中使用动画调整 CALayer 的大小

swift CALayer的+帮手

Swift开发之CALayer---- Modifying the Layer's Appearance

CALayer 委托仅在使用 Swift 时偶尔调用