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")
}
我的主要问题现在是:
- 如何在 CAShapeLayer 中设置图像?我试过:固定
从 init
调用它
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)
- 我还需要动画化这个过程,我已经尝试过回复
@s0urce 但不幸的是,它不是绘图。我需要做吗
还有什么?
永远不要在 drawRect
方法中添加子层。在视图的 init
或 initWithFrame:
方法内或至少在视图控制器的 viewDidLoad
方法内执行此操作会好得多。
您需要设置 CAShapeLayer
的边界,否则它将是 CGRectZero
。不要忘记 UIBezierPath
的点应该在 CAShapeLayer
.
的坐标系中
彩色动画示例代码:
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")
我需要画一个这样的形状:
----第一部分已解决,现在出现绘图,但我如何制作动画?----
这是我在 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")
}
我的主要问题现在是:
- 如何在 CAShapeLayer 中设置图像?我试过:固定 从 init 调用它
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)
- 我还需要动画化这个过程,我已经尝试过回复 @s0urce 但不幸的是,它不是绘图。我需要做吗 还有什么?
永远不要在
drawRect
方法中添加子层。在视图的init
或initWithFrame:
方法内或至少在视图控制器的viewDidLoad
方法内执行此操作会好得多。您需要设置
CAShapeLayer
的边界,否则它将是CGRectZero
。不要忘记UIBezierPath
的点应该在CAShapeLayer
. 的坐标系中
彩色动画示例代码:
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")