斯威夫特 - 如何动画画线不直接?只能绘制rect吗?

时间:2016-07-14 23:09:56

标签: swift

我之前已经看过这个问题,但尚未找到答案。我已经有一段时间了,需要知道如何设置LINE的动画而不是矩形。

从我可以看到,动画从笔画到盒子是非常不同的。这里只需要一些指示 -

我有一个在视图加载上绘制的边框(不是动画,它只是绘制它):

 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);

我从另一个答案得到了这个,并试图把它分开。当视图加载时,我需要从中心动画/生长出来的线条,就像增长到与此处绘制的相同的宽度和大小但是动画。

我不知道如何做到这一点,但是另一个答案通过在这里将边框设置为零来实现我需要的效果:

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完全不同的代码,我不知道如何将两者结合起来。我在哪里错了?当我做第二个活动边界时,我如何从中心抽出我的第一个边界?

1 个答案:

答案 0 :(得分:0)

使用CAShapeLaterUIBezierPathCABasicAnimation动画绘制线条。

以下是示例代码:

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)
    }

}

viewDidLoad

ViewController中的代码
// ...
let sampleView = SampleView()
sampleView.frame = CGRectMake(10, 60, 240, 50)
sampleView.backgroundColor = UIColor.lightGrayColor()
view.addSubview(sampleView)

以下是捕获:

enter image description here

注意:如果你在iOS9模拟器中运行代码(我没有测试过早期版本),动画可能会被阻止。选择在真实设备或iOS10模拟器中运行它。