【问题标题】:CAShapeLayer mask reveal from bottomCAShapeLayer 蒙版从底部显露出来
【发布时间】:2015-07-19 14:56:58
【问题描述】:

我正在尝试从图像底部创建“显示”效果。 我认为这就像将 anchorPoint 设置为 CGPointMake(0.5, 1.0) 或将 contentsGravity 设置为 kCAGravityTop 一样简单,但是这些选项都不起作用。

我当前的代码可以工作,但从上到下动画。这是一个揭示的想法:http://giphy.com/gifs/xTiTnBzItdgaD1xHMc

我如何让这个从下到上进行?

这是代码

    let path                = UIBezierPath(rect: CGRectMake(0, 0, imgEmptyBase.width, imgEmptyBase.height - 80))
    let mask                = CAShapeLayer()
    mask.anchorPoint        = CGPointMake(0.5, 1.0)
    mask.path               = path.CGPath

    imgEmptyBase.layer.mask = mask

    let anim                = CABasicAnimation(keyPath: "path")

    anim.fromValue          = path.CGPath
    anim.toValue            = UIBezierPath(rect: imgEmptyBase.bounds).CGPath
    anim.duration           = 1.0
    anim.fillMode           = kCAFillModeForwards
    anim.removedOnCompletion = false

    imgEmptyBase.layer.mask.addAnimation(anim, forKey: "anim")

【问题讨论】:

    标签: ios swift calayer cashapelayer


    【解决方案1】:

    这将完全达到您所追求的效果:

    let path = UIBezierPath(rect: CGRectMake(0, imgEmptyBase.layer.frame.size.height, imgEmptyBase.layer.frame.size.width, imgEmptyBase.layer.frame.size.height))
    let mask = CAShapeLayer()
    mask.path = path.CGPath
    
    imgEmptyBase.layer.mask = mask
    
    let revealPath = UIBezierPath(rect: CGRectMake(0, 0, imgEmptyBase.layer.frame.size.width, imgEmptyBase.layer.frame.size.height))
    
    let anim                = CABasicAnimation(keyPath: "path")
    anim.fromValue          = path.CGPath
    anim.toValue            = revealPath.CGPath
    anim.duration           = 1.0
    anim.fillMode           = kCAFillModeForwards
    anim.removedOnCompletion = false
    
    imgEmptyBase.layer.mask.addAnimation(anim, forKey: "anim")
    

    这完全是关于使用正确的“from”和“to”值更改掩码路径。例如:将初始遮罩路径设置为CGRectMake(0, 0, imgEmptyBase.layer.frame.size.width, 0),将revealPath 设置为CGRectMake(0, 0, imgEmptyBase.layer.frame.size.width, imgEmptyBase.layer.frame.size.height),会产生“从上到下”的显示效果。

    【讨论】:

      【解决方案2】:

      我的建议是使用路径的笔触而不是填充。

      您绘制一条路径(蓝线),该路径从图层底部开始,到顶部结束,水平居中,线宽与图层宽度相同。
      红色轮廓表示笔划轮廓。

      您在 strokeEnd 属性上播放从 0 到 1 的动画。

      I made a playground如果你想看看我是如何做到这一点的。

      我更新了上面的链接。
      我把代码放在你仍然无法进入操场的情况下

      let aView = UIView(frame:CGRect(x:0 y:0 width:200 height:200))
      aView.backgroundColor = UIColor.redColor() // the view that needs to be masked
      let shapeLayer = CAShapeLayer()
      shapeLayer.bounds = aView.bounds
      let bezierPath = UIBezierPath()
      bezierPath.moveToPoint(CGPoint(x: shapeLayer.bounds.width/2, y: shapeLayer.bounds.height))
      bezierPath.addLineToPoint(CGPoint(x: shapeLayer.bounds.width/2, y: 0))
      shapeLayer.path = bezierPath.CGPath
      shapeLayer.fillColor = UIColor.clearColor().CGColor
      shapeLayer.strokeColor = UIColor.redColor().CGColor
      shapeLayer.lineWidth = shapeLayer.bounds.width
      shapeLayer.position = CGPoint(x: aView.frame.width/2, y: aView.frame.height/2)
      shapeLayer.strokeEnd = 1
      
      let animation = CABasicAnimation(keyPath: "strokeEnd")
      animation.fromValue = 0
      animation.toValue = 1
      animation.duration = 4
      animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
      shapeLayer.addAnimation(animation, forKey: "stroneAnimation")
      shapeLayer.strokeEnd = 1
      aView.layer.mask = shapeLayer
      

      【讨论】:

      • 您的游乐场链接无效。你能提供一些代码吗?
      • 我用新链接更新了帖子并粘贴了代码
      【解决方案3】:

      我想到了 (2) 个选项。

      一种是仅将动画从值切换到值:

      let path                = UIBezierPath(rect: CGRectMake(0, 0, imgEmptyBase.width, imgEmptyBase.height - 80))
      let mask                = CAShapeLayer()
      mask.anchorPoint        = CGPointMake(0.5, 1.0)
      mask.path               = path.CGPath
      
      imgEmptyBase.layer.mask = mask
      
      let anim                = CABasicAnimation(keyPath: "path")
      
      anim.fromValue          = UIBezierPath(rect: imgEmptyBase.bounds).CGPath
      anim.toValue            = path.CGPath
      anim.duration           = 1.0
      anim.fillMode           = kCAFillModeForwards
      anim.removedOnCompletion = false
      
      imgEmptyBase.layer.mask.addAnimation(anim, forKey: "anim")
      

      另一种是自己切换贝塞尔路径声明:

      let path                = UIBezierPath(rect: imgEmptyBase.bounds).CGPath
      let mask                = CAShapeLayer()
      mask.anchorPoint        = CGPointMake(0.5, 1.0)
      mask.path               = path.CGPath
      
      imgEmptyBase.layer.mask = mask
      
      let anim                = CABasicAnimation(keyPath: "path")
      
      anim.fromValue          = path.CGPath
      anim.toValue            = UIBezierPath(rect: CGRectMake(0, 0, imgEmptyBase.width, imgEmptyBase.height - 80))
      anim.duration           = 1.0
      anim.fillMode           = kCAFillModeForwards
      anim.removedOnCompletion = false
      
      imgEmptyBase.layer.mask.addAnimation(anim, forKey: "anim")
      

      【讨论】:

      • 这两个选项都隐藏了该项目...我想显示它。翻转值并不能解决问题...
      【解决方案4】:

      检查一下!!

      let path = UIBezierPath(rect: CGRectMake(0, denterImage.frame.origin.y, denterImage.bounds.size.width, denterImage.bounds.size.height - 200))
      let mask = CAShapeLayer()
      mask.anchorPoint = CGPointMake(0.5, 1.0)
      mask.path = path.CGPath
      
      denterImage.layer.mask = mask
      
      let anim = CABasicAnimation(keyPath: "path")
      
      anim.fromValue = path.CGPath
      anim.toValue = UIBezierPath(rect: denterImage.bounds).CGPath
      anim.duration =  1.5
      anim.fillMode = kCAFillModeForwards
      anim.removedOnCompletion = false
      
      denterImage.layer.mask.addAnimation(anim, forKey: "anim")
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-08-06
        • 1970-01-01
        • 1970-01-01
        • 2013-09-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多