UIImage 内部自定义形状和动画

UIImage Inside Custom Shape and animation

我需要画一个这样的形状: 并在滚动时为颜色路径设置动画。我已经尝试了几件事 2 个小时,但没有找到克服它的最终方法。我已经尝试创建一个自定义 UIView,创建一个 CShapeLayer,然后创建一个 UIBezierPath 到该层,最后将子视图添加到 viewdidload 中的一个视图,但这不起作用。我还能做些什么来解决这个问题?我将从最复杂的形状开始,因为标签将与形状对齐。

----第一部分已解决,现在出现绘图,但我如何制作动画?----

这是我在 drawRect 方法中更新的代码。

class CustomOval: UIView {

override init(frame: CGRect) {
    super.init(frame: frame)
}

required init(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)!
}

override func drawRect(rect: CGRect) {

    //SHAPE 2
    let rectanglePath2 = UIBezierPath(roundedRect: CGRectMake(135, 177, 20, 70), cornerRadius: 0)

    let shapeLayer2 = CAShapeLayer()
    shapeLayer2.path = rectanglePath2.CGPath
    shapeLayer2.bounds = CGRect(x: 135, y: 177, width: 20, height: 70)
    shapeLayer2.lineWidth = 5.0

    let label2 = UILabel()
    label2.frame = CGRectMake(150 + rectanglePath2.bounds.width, rectanglePath2.bounds.height + 120, 100, 50)
    label2.text = "Label 2"

    self.addSubview(label2)

    //// Rectangle Drawing
    UIColor.blueColor().setFill()
    rectanglePath2.fill()

    //SHAPE 3
    let rectanglePath3 = UIBezierPath(roundedRect: CGRectMake(135, 237, 20, 70), cornerRadius: 0)

    let shapeLayer3 = CAShapeLayer()
    shapeLayer3.path = rectanglePath3.CGPath
    shapeLayer3.bounds = CGRect(x: 135, y: rectanglePath2.bounds.maxY, width: 20, height: 70)
    shapeLayer3.lineWidth = 5.0

    //// Rectangle Drawing
    UIColor.redColor().setFill()
    rectanglePath3.fill()

    let label3 = UILabel()
    label3.frame = CGRectMake(rectanglePath3.bounds.width + 150, rectanglePath3.bounds.height + 190, 100, 50)
    label3.text = "Label 3"

    self.addSubview(label3)

    //SHAPE 1
    let rectanglePath = UIBezierPath(roundedRect: CGRectMake(104, 24, 80, 155), cornerRadius: 40)

    let shapeLayer = CAShapeLayer()
    shapeLayer.path = rectanglePath.CGPath
    shapeLayer.bounds = CGRect(x: 104, y: 24, width: 80, height: 155)
    shapeLayer.lineWidth = 5.0

    //// Rectangle Drawing
    UIColor.grayColor().setFill()
    rectanglePath.fill()

}

}

-更新动画-

var shapeLayer = CAShapeLayer()

override init(frame: CGRect) {
    shapeLayer = CAShapeLayer()
    super.init(frame: frame)
    animateShape1()

}

required init(coder aDecoder: NSCoder) {
    shapeLayer = CAShapeLayer()
    super.init(coder: aDecoder)!
    animateShape1()
}

func animateShape1(){

    let animation = CABasicAnimation(keyPath: "fillColor")

    animation.fromValue = UIColor.whiteColor().CGColor
    animation.toValue = UIColor.redColor().CGColor
    animation.duration = 5 //2 sec

    shapeLayer.fillColor = UIColor.redColor().CGColor //color end value
    layer.addAnimation(animation, forKey: "somekey")


}

我的主要问题现在是:

func addImage(){

    let imageSubLayer = CALayer()
    let image = UIImage(named: "paint.png")
    imageSubLayer.contents = image?.CGImage
    imageSubLayer.bounds = (frame: CGRect(x: shapeLayer.bounds.width/2, y:   shapeLayer.bounds.height/2, width: 50, height: 50))
    shapeLayer.addSublayer(imageSubLayer)

}

我也试过,有效的方法是:但我不想要平铺图像。我也试过没有平铺,但这是行不通的

CGContextSaveGState(context)
rectanglePath.addClip()
CGContextScaleCTM(context, 0, (image?.size.height)!)
CGContextDrawTiledImage(context, CGRectMake(20, 20, 50, 50), image!.CGImage)
CGContextRestoreGState(context)
  1. 永远不要在 drawRect 方法中添加子层。在视图的 initinitWithFrame: 方法内或至少在视图控制器的 viewDidLoad 方法内执行此操作会好得多。

  2. 您需要设置 CAShapeLayer 的边界,否则它将是 CGRectZero。不要忘记 UIBezierPath 的点应该在 CAShapeLayer.

  3. 的坐标系中

彩色动画示例代码:

let animation = CABasicAnimation(keyPath: "fillColor")

animation.fromValue = UIColor.whiteColor().CGColor
animation.toValue = UIColor.redColor().CGColor
animation.duration = 2 //2 sec

layer.fillColor = UIColor.redColor().CGColor //color end value
layer.addAnimation(animation, forKey: "somekey")