我之前已经查过这个问题,但尚未找到答案。我已经从事这个工作有一段时间了,需要知道如何为直线而不是矩形制作动画。
据我所知,从笔划到方框的动画非常不同。这里只需要一些指示 -
我在这里有一个在 View 加载时绘制的边框(不是用动画,它只是绘制它):
override public func drawRect(rect: CGRect){
super.drawRect(rect)
let borderColor = self.hasError! ? kDefaultActiveColor : kDefaultErrorColor
let textRect = self.textRectForBounds(rect)
let context = UIGraphicsGetCurrentContext()
let borderlines : [CGPoint] = [CGPointMake(0, CGRectGetHeight(textRect) - 1),
CGPointMake(CGRectGetWidth(textRect), CGRectGetHeight(textRect) - 1)]
if self.enabled {
CGContextBeginPath(context);
CGContextAddLines(context, borderlines, 2);
CGContextSetLineWidth(context, 1.3);
CGContextSetStrokeColorWithColor(context, borderColor.CGColor);
CGContextStrokePath(context);
我从另一个答案中得到了这个,并试图将其拆开。当 View 加载时,我需要该线从其中心进行动画/生长,就像生长到与此处绘制的但动画相同的宽度和大小。
我不知道如何实现这一点,但是另一个答案通过在此处将边框大小设置为零达到了我需要的效果:
self.activeBorder = UIView(frame: CGRectZero)
self.activeBorder.backgroundColor = kDefaultActiveColor
//self.activeBorder.backgroundColor = kDefaultActiveBorderColor
self.activeBorder.layer.opacity = 0
self.addSubview(self.activeBorder)
并使用动画:
self.borderlines.transform = CATransform3DMakeScale(CGFloat(0.01), CGFloat(1.0), 1)
self.activeBorder.layer.opacity = 1
CATransaction.begin()
self.activeBorder.layer.transform = CATransform3DMakeScale(CGFloat(0.03), CGFloat(1.0), 1)
let anim2 = CABasicAnimation(keyPath: "transform")
let fromTransform = CATransform3DMakeScale(CGFloat(0.01), CGFloat(1.0), 1)
let toTransform = CATransform3DMakeScale(CGFloat(1.0), CGFloat(1.0), 1)
anim2.fromValue = NSValue(CATransform3D: fromTransform)
anim2.toValue = NSValue(CATransform3D: toTransform)
anim2.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
anim2.fillMode = kCAFillModeForwards
anim2.removedOnCompletion = false
self.activeBorder.layer.addAnimation(anim2, forKey: "_activeBorder")
CATransaction.commit()
这似乎使用了与我原来的 drawRect
完全不同的代码,我不知道如何将两者结合起来。我这里哪里出错了?如何像绘制第二个事件边框一样从中心绘制第一个边框?
最佳答案
使用CAShapeLater
、UIBezierPath
和CABasicAnimation
来动画绘制线条。
这里是示例代码:
class SampleView: UIView {
override public func drawRect(rect: CGRect) {
let leftPath = UIBezierPath()
leftPath.moveToPoint(CGPointMake(CGRectGetMidX(frame), CGRectGetHeight(frame)))
leftPath.addLineToPoint(CGPointMake(0, CGRectGetHeight(frame)))
let rightPath = UIBezierPath()
rightPath.moveToPoint(CGPointMake(CGRectGetMidX(frame), CGRectGetHeight(frame)))
rightPath.addLineToPoint(CGPointMake(CGRectGetWidth(frame), CGRectGetHeight(frame)))
let leftShapeLayer = CAShapeLayer()
leftShapeLayer.path = leftPath.CGPath
leftShapeLayer.strokeColor = UIColor.redColor().CGColor;
leftShapeLayer.lineWidth = 1.3
leftShapeLayer.strokeEnd = 0
layer.addSublayer(leftShapeLayer)
let rightShpaeLayer = CAShapeLayer()
rightShpaeLayer.path = rightPath.CGPath
rightShpaeLayer.strokeColor = UIColor.redColor().CGColor;
rightShpaeLayer.lineWidth = 1.3
rightShpaeLayer.strokeEnd = 0
layer.addSublayer(rightShpaeLayer)
let drawLineAnimation = CABasicAnimation(keyPath: "strokeEnd")
drawLineAnimation.toValue = NSNumber(float: 1)
drawLineAnimation.duration = 1
drawLineAnimation.fillMode = kCAFillModeForwards
drawLineAnimation.removedOnCompletion = false
leftShapeLayer.addAnimation(drawLineAnimation, forKey: nil)
rightShpaeLayer.addAnimation(drawLineAnimation, forKey: nil)
}
}
ViewController
的viewDidLoad
中的代码
// ...
let sampleView = SampleView()
sampleView.frame = CGRectMake(10, 60, 240, 50)
sampleView.backgroundColor = UIColor.lightGrayColor()
view.addSubview(sampleView)
这是捕获的内容:
注意:如果你在iOS9模拟器中运行代码(我没有测试过早期版本),动画可能会被阻止。选择在真实设备或iOS10模拟器中运行。
关于Swift - 如何动画地绘制线条而不是矩形?只能画矩形吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38385599/