Swift - 如何动画地绘制线条而不是矩形?只能画矩形吗?

标签 swift

我之前已经查过这个问题,但尚未找到答案。我已经从事这个工作有一段时间了,需要知道如何为直线而不是矩形制作动画。

据我所知,从笔划到方框的动画非常不同。这里只需要一些指示 -

我在这里有一个在 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 完全不同的代码,我不知道如何将两者结合起来。我这里哪里出错了?如何像绘制第二个事件边框一样从中心绘制第一个边框?

最佳答案

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

}

ViewControllerviewDidLoad中的代码

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

这是捕获的内容:

enter image description here

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

关于Swift - 如何动画地绘制线条而不是矩形?只能画矩形吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38385599/

相关文章:

swift - Console 在 Swift 中继续输出包装为 Optional 的字符串,为什么?

ios - swift 中的 Collection View 单元格高度和宽度

ios - 将 UIPanGesture 转换为 UITableView 滚动

ios - 即使我在 iOS 的另一个选项卡中,如何返回 Root View Controller ?

swift - SKAction 运行操作中的代码未执行

ios - 继续记录丢失的服务器连接以获取 kct 连接无效通知

swift - Firebase 快照以在 Swift 中标记

ios - Android 的 startActivityForResult/setResult 的 iOS 等效项是什么?

swift - 这是我解决八皇后难题的快速代码

swift - Swift4 转换后 "' init ' is deprecated"警告