Ios 如何使用CoreGrahpics绘制文本&;核心动画

Ios 如何使用CoreGrahpics绘制文本&;核心动画,ios,objective-c,swift3,core-graphics,swift4,Ios,Objective C,Swift3,Core Graphics,Swift4,我想实现这种类型的动画。请检查此URL 我正在添加我在项目中使用过的代码,在项目中我使用了核心图形来渲染带有动画的文本,但我无法为所提到的链接中显示的文本设置动画 这是我用来在屏幕上呈现文本的代码 let context = UIGraphicsGetCurrentContext()! context.saveGState() context.setAlpha(noLightText) let nOLIGHTRect = CGRect(x: 145.66, y

我想实现这种类型的动画。请检查此URL

我正在添加我在项目中使用过的代码,在项目中我使用了核心图形来渲染带有动画的文本,但我无法为所提到的链接中显示的文本设置动画

这是我用来在屏幕上呈现文本的代码

    let context = UIGraphicsGetCurrentContext()!
    context.saveGState()
    context.setAlpha(noLightText)

    let nOLIGHTRect = CGRect(x: 145.66, y: 590, width: 449.38, height: 125)
    let nOLIGHTStyle = NSMutableParagraphStyle()
    nOLIGHTStyle.alignment = .center
    let nOLIGHTFontAttributes = [
        .font: UIFont(name: "Futura-CondensedExtraBold", size: 96)!,
        .foregroundColor: nOLIGHTColor,
        .paragraphStyle: nOLIGHTStyle,
        ] as [NSAttributedStringKey: Any]

    "NO LIGHT".draw(in: nOLIGHTRect, withAttributes: nOLIGHTFontAttributes)

    context.restoreGState()


    //// LOW LIGHT Drawing
    context.saveGState()
    context.setAlpha(_0)

    let lOWLIGHTRect = CGRect(x: 145.94, y: 590, width: 449.38, height: 125)
    let lOWLIGHTStyle = NSMutableParagraphStyle()
    lOWLIGHTStyle.alignment = .left
    let lOWLIGHTFontAttributes = [
        .font: UIFont(name: "Futura-CondensedExtraBold", size: 96)!,
        .foregroundColor: lOWLIGHTColor,
        .paragraphStyle: lOWLIGHTStyle,
        ] as [NSAttributedStringKey: Any]

    "LOW LIGHT".draw(in: lOWLIGHTRect, withAttributes: lOWLIGHTFontAttributes)

    context.restoreGState()


    //// MID LIGHT Drawing
    context.saveGState()
    context.setAlpha(mediumLightText)

    let mIDLIGHTRect = CGRect(x: 145.77, y: 590, width: 449.38, height: 125)
    let mIDLIGHTStyle = NSMutableParagraphStyle()
    mIDLIGHTStyle.alignment = .left
    let mIDLIGHTFontAttributes = [
        .font: UIFont(name: "Futura-CondensedExtraBold", size: 96)!,
        .foregroundColor: mIDLIGHTColor,
        .paragraphStyle: mIDLIGHTStyle,
        ] as [NSAttributedStringKey: Any]


    "MID LIGHT".draw(in: mIDLIGHTRect, withAttributes: mIDLIGHTFontAttributes)

    context.restoreGState()

如果要同时为多个角色的轮廓笔划设置动画,可以:

  • 确定每个字符的CG路径
  • 将cgpath映射到CAShapeLayers
  • 设置
    strokeEnd
    属性的动画
这看起来像这样:

请注意: iOS使用的字体是使用TrueType或OpenType格式的轮廓字体。这意味着每个图示符都使用直线和曲线来定义其边界。渲染轮廓时,我们通常看到的是填充区域。因此,如果“strokeEnd”属性已设置动画,则会绘制图示符的轮廓。下面的代码显示了如何实现这一点

以人类书写文本的方式制作文本动画需要更多的努力(例如,使用笔划字体而不是轮廓字体加上相关引擎,或者使用用户定义的代表每个字符的向量路径)

var charLayers=[CAShapeLayer]()
覆盖函数视图显示(u动画:Bool){
super.viewdide显示(动画)
对于self.charLayers中的层{
layer.removeFromSuperlayer()
}
let stringAttributes=[NSAttributedStringKey.font:UIFont(名称:“Futura ConcurrentDextraBold”,大小:64.0)!]
让attributedString=NSMutableAttributedString(字符串:“hello world”,属性:stringAttributes)
设charPaths=self.characterPaths(attributedString:attributedString,位置:CGPoint(x:24,y:192))
self.charLayers=charPaths.map{path->CAShapeLayer in
设shapeLayer=CAShapeLayer()
shapeLayer.fillColor=UIColor.clear.cgColor
shapeLayer.strokeColor=UIColor.red.cgColor
shapeLayer.lineWidth=2
shapeLayer.path=路径
回程成形器
}
对于self.charLayers中的层{
view.layer.addSublayer(层)
让动画=动画化(关键路径:“strokeEnd”)
animation.fromValue=0
动画。持续时间=2.2
添加(动画,forKey:“角色化”)
}
}
func字符路径(attributedString:NSAttributedString,位置:CGPoint)->[CGPath]{
let line=CTLineCreateWithAttributedString(attributedString)
guard let glyphRuns=CTLineGetGlyphRuns(行)作为?[CTRun]else{return[]}
变量CharacterPath=[CGPath]()
对于glyphRun中的glyphRun{
guard let attributes=CtrunGetAttribute(glyphRun)作为?[String:AnyObject]其他{continue}
让font=attributes[kCTFontAttributeName作为字符串]作为!CTFont

对于0中的索引。如果有人能推荐一本关于CAShapeLayer和动画的基本入门书,我希望它能将属性字符串转换成CGPath或BezierPath。然后将该路径设置为CAShapeLayer并设置笔划。使用CABasicAnimation和voila对笔划进行动画制作。谢谢你的回答。你能提供任何代码吗提供所需动画我们如何添加用于绘制文本的帧?我想为字形显示一条路径。请帮助我如何为角色显示单行线?我在目标C中转换,但我在将动画单独放置在角色中时遇到问题。我在self.charLayers中的层中遇到问题{view.layer.addSublayer(layer)let animation=CABasicAnimation(keyPath:“strokeEnd”)animation.fromValue=0 animation.duration=2.2 layer.add(animation,forKey:“charAnimation”)}您能帮我找出这个对象的c等价物吗?fromValue声明为
@属性(可空,强)id fromValue;
在Objective-C中,请参阅
CAAnimation.h
。因此您需要编写:
animation.fromValue=@(0.0);
而不是指定0。
var charLayers = [CAShapeLayer]()

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    for layer in self.charLayers {
        layer.removeFromSuperlayer()
    }

    let stringAttributes = [ NSAttributedStringKey.font: UIFont(name: "Futura-CondensedExtraBold", size: 64.0)! ]
    let attributedString = NSMutableAttributedString(string: "hello world", attributes: stringAttributes )
    let charPaths = self.characterPaths(attributedString: attributedString, position: CGPoint(x: 24, y: 192))

    self.charLayers = charPaths.map { path -> CAShapeLayer in
        let shapeLayer = CAShapeLayer()
        shapeLayer.fillColor = UIColor.clear.cgColor
        shapeLayer.strokeColor = UIColor.red.cgColor
        shapeLayer.lineWidth = 2
        shapeLayer.path = path
        return shapeLayer
    }

    for layer in self.charLayers {
        view.layer.addSublayer(layer)
        let animation = CABasicAnimation(keyPath: "strokeEnd")
        animation.fromValue = 0
        animation.duration = 2.2
        layer.add(animation, forKey: "charAnimation")
    }
}

func characterPaths(attributedString: NSAttributedString, position: CGPoint) -> [CGPath] {

    let line = CTLineCreateWithAttributedString(attributedString)

    guard let glyphRuns = CTLineGetGlyphRuns(line) as? [CTRun] else { return []}

    var characterPaths = [CGPath]()

    for glyphRun in glyphRuns {
        guard let attributes = CTRunGetAttributes(glyphRun) as? [String:AnyObject] else { continue }
        let font = attributes[kCTFontAttributeName as String] as! CTFont

        for index in 0..<CTRunGetGlyphCount(glyphRun) {
            let glyphRange = CFRangeMake(index, 1)

            var glyph = CGGlyph()
            CTRunGetGlyphs(glyphRun, glyphRange, &glyph)

            var characterPosition = CGPoint()
            CTRunGetPositions(glyphRun, glyphRange, &characterPosition)
            characterPosition.x += position.x
            characterPosition.y += position.y

            if let glyphPath = CTFontCreatePathForGlyph(font, glyph, nil) {
                var transform = CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: characterPosition.x, ty: characterPosition.y)
                if let charPath = glyphPath.copy(using: &transform) {
                    characterPaths.append(charPath)
                }
            }
        }
    }
    return characterPaths
}