Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Swift/iOS设置手写笔划的动画?_Ios_Swift_Core Animation_Uibezierpath_Cgpath - Fatal编程技术网

如何使用Swift/iOS设置手写笔划的动画?

如何使用Swift/iOS设置手写笔划的动画?,ios,swift,core-animation,uibezierpath,cgpath,Ios,Swift,Core Animation,Uibezierpath,Cgpath,目标 import CoreText import Foundation import UIKit import QuartzCore import XCPlayground //research layers //var l:CALayer? = nil //var txt:CATextLayer? = nil //var r:CAReplicatorLayer? = nil //var tile:CATiledLayer? = nil //var trans:CATransformLaye

目标

import CoreText
import Foundation
import UIKit
import QuartzCore
import XCPlayground

//research layers
//var l:CALayer? = nil
//var txt:CATextLayer? = nil
//var r:CAReplicatorLayer? = nil
//var tile:CATiledLayer? = nil
//var trans:CATransformLayer? = nil
//var b:CAAnimation?=nil

//  Setup playground to run in full simulator (⌘-0:Select Playground File; ⌘-alt-0:Choose option Run in Full Simulator)

//approach 2 using a custom stroke font requires special font without an outline whose path is the actual fill
var customFontPath = NSBundle.mainBundle().pathForResource("cwTeXFangSong-zhonly", ofType: "ttf")

//  Within the playground folder create Resources folder to hold fonts. NB - Sources folder can also be created to hold additional Swift files
//ORTE1LOT.otf
//NISC18030.ttf
//cwTeXFangSong-zhonly
//cwTeXHei-zhonly
//cwTeXKai-zhonly
//cwTeXMing-zhonly
//cwTeXYen-zhonly

var customFontData = NSData(contentsOfFile: customFontPath!) as! CFDataRef
var error:UnsafeMutablePointer<Unmanaged<CFError>?> = nil
var provider:CGDataProviderRef = CGDataProviderCreateWithCFData ( customFontData )
var customFont = CGFontCreateWithDataProvider(provider) as CGFont!

let registered =  CTFontManagerRegisterGraphicsFont(customFont, error)

if !registered  {
    println("Failed to load custom font: ")

}

let string:NSString = "五"
//"ABCDEFGHIJKLMNOPQRSTUVWXYZ一二三四五六七八九十什我是美国人"

//use the Postscript name of the font
let font =  CTFontCreateWithName("cwTeXFangSong", 72, nil)
//HiraMinProN-W6
//WeibeiTC-Bold
//OrachTechDemo1Lotf
//XinGothic-Pleco-W4
//GB18030 Bitmap

var count = string.length

//must initialize with buffer to enable assignment within CTFontGetGlyphsForCharacters
var glyphs = Array<CGGlyph>(count: string.length, repeatedValue: 0)
var chars = [UniChar]()

for index in 0..<string.length {

    chars.append(string.characterAtIndex(index))

}

//println ("\(chars)") //ok

//println(font)
//println(chars)
//println(chars.count)
//println(glyphs.count)

let gotGlyphs = CTFontGetGlyphsForCharacters(font, &chars, &glyphs, chars.count)

//println(glyphs)
//println(glyphs.count)

if gotGlyphs {

    // loop and pass paths to animation function
    let cgpath = CTFontCreatePathForGlyph(font, glyphs[0], nil)

    //how to break the path apart?
    let path = UIBezierPath(CGPath: cgpath)
    //path.hashValue
    //println(path)

    //  all shapes are closed paths
    //  how to distinguish overlapping shapes, confluence points connected by line segments?
    //  compare curve angles to identify stroke type
    //  for curves that intersect find confluence points and create separate line segments by adding the linesegmens between the gap areas of the intersection

    /* analysis of movepoint

        This method implicitly ends the current subpath (if any) and 
        sets the current point to the value in the point parameter. 
        When ending the previous subpath, this method does not actually 
        close the subpath. Therefore, the first and last points of the 
        previous subpath are not connected to each other.

        For many path operations, you must call this method before 
        issuing any commands that cause a line or curve segment to be 
        drawn.
*/


    //CGPathApplierFunction should allow one to add behavior to each glyph obtained from a string (Swift version??)

//    func processPathElement(info:Void,  element: CGPathElement?) {
//        var pointsForPathElement=[UnsafeMutablePointer<CGPoint>]()
//        if let e = element?.points{
//            pointsForPathElement.append(e)
//            
//        }
//    }
//    
//    var pathArray = [CGPathElement]() as! CFMutableArrayRef

    //var pathArray = Array<CGPathElement>(count: 4, repeatedValue: 0)

    //CGPathApply(<#path: CGPath!#>, <#info: UnsafeMutablePointer<Void>#>, function: CGPathApplierFunction)


//    CGPathApply(path.CGPath, info: &pathArray, function:processPathElement)

    /*
    NSMutableArray *pathElements = [NSMutableArray arrayWithCapacity:1];
    // This contains an array of paths, drawn to this current view
    CFMutableArrayRef existingPaths = displayingView.pathArray;
    CFIndex pathCount = CFArrayGetCount(existingPaths);
    for( int i=0; i < pathCount; i++ ) {
    CGMutablePathRef pRef = (CGMutablePathRef) CFArrayGetValueAtIndex(existingPaths, i);
    CGPathApply(pRef, pathElements, processPathElement);
    }
    */

    //given the structure
    let pathString = path.description
//    println(pathString)
    //regex patthern matcher to produce subpaths?
    //...
    //must be simpler method
    //...

    /* 
        NOTES:
        Use assistant editor to view 
        UIBezierPath String

        http://www.google.com/fonts/earlyaccess
        Stroke-based fonts
        Donald Knuth

    */
//    var redColor = UIColor.redColor()
//    redColor.setStroke()


    var pathLayer = CAShapeLayer()
    pathLayer.frame = CGRect(origin: CGPointZero, size: CGSizeMake(300.0,300.0))
    pathLayer.lineJoin = kCALineJoinRound
    pathLayer.lineCap = kCALineCapRound
    //pathLayer.backgroundColor = UIColor.whiteColor().CGColor
    pathLayer.strokeColor = UIColor.redColor().CGColor
    pathLayer.path = path.CGPath


    //    pathLayer.backgroundColor = UIColor.redColor().CGColor

    // regarding strokeStart, strokeEnd
    /* These values define the subregion of the path used to draw the
    * stroked outline. The values must be in the range [0,1] with zero
    * representing the start of the path and one the end. Values in
    * between zero and one are interpolated linearly along the path
    * length. strokeStart defaults to zero and strokeEnd to one. Both are
    * animatable. */
    var pathAnimation = CABasicAnimation(keyPath: "strokeEnd")
    pathAnimation.duration = 10.0
    pathAnimation.fromValue = NSNumber(float: 0.0)
    pathAnimation.toValue = NSNumber(float: 1.0)

    /*
    var fillAnimation = CABasicAnimation (keyPath: "fill")
    fillAnimation.fromValue = UIColor.blackColor().CGColor
    fillAnimation.toValue = UIColor.blueColor().CGColor
    fillAnimation.duration = 10.0
   pathLayer.addAnimation(fillAnimation, forKey: "fillAnimation") */

    //given actual behavior of boundary animation, it is more likely that some other animation will better simulate a written stroke

    var someView = UIView(frame: CGRect(origin: CGPointZero, size: CGSizeMake(300.0, 300.0)))
    someView.layer.addSublayer(pathLayer)


    //SHOW VIEW IN CONSOLE (ASSISTANT EDITOR)
     XCPShowView("b4Animation", someView)

    pathLayer.addAnimation(pathAnimation, forKey: "strokeEndAnimation")

    someView.layer.addSublayer(pathLayer)

    XCPShowView("Animation", someView)




}
我试图创建一个人类书写的动画近似,使用一个由字形生成的UIBezierPath。我理解并阅读了许多听起来与我相似(但不同)的UIBezierPath问题。我的目标是创建一个动画,近似于人类书写角色和字母的样子

背景

我已经创建了一个游乐场,我正在使用它来更好地理解路径,以便在设置图示符动画时使用,就像它们是手工绘制的一样

Apple CAShapeLayer中的几个概念(strokeStart和strokeEnd)在动画制作时似乎并没有像预期的那样运行。我认为,一般来说,人们倾向于认为笔划是用书写工具完成的(基本上是直线或曲线)。我们认为笔画和填充是一条直线,因为我们的书写工具不区分笔划和填充。 但是当设置动画时,路径的轮廓由线段构成(填充单独处理,不清楚如何设置填充位置的动画?)。我想要实现的是一条自然的人类书写的直线/曲线,它显示了笔划的开始和结束,以及动画从开始到结束移动时添加的填充部分。起初,这看起来很简单,但我认为可能需要设置填充位置动画(不确定如何执行)、笔划开始/结束(鉴于上述动画执行方式的意外警告,不确定是否需要),以及使用子路径(如何从已知路径重建)

方法1

因此,我考虑了路径的概念(CGPath/UIBezierPath)。每个路径实际上包含构造图示符所需的所有子路径,因此,递归这些子路径并使用CAKeyframeAnimation/CABasicAnimations和显示部分构造的子路径的动画组可能是一种好方法(尽管每个子路径的填充位置和笔划仍然需要从头到尾设置动画?)

这种方法引出了一个精炼的问题:

如果有完整的UIBezierPath/CGPath,如何访问和创建UIBezierPath/CGPath(子路径)

如何使用路径/子路径信息设置填充和笔划的动画,就像使用书写工具绘制一样?(似乎这意味着需要同时设置CALayer的strokeStart/strokeEnd、position和path属性的动画)

注意:

正如人们在代码中所看到的,我确实从字形中获得了完整的路径。我可以看到路径描述为我提供了类似路径的信息。人们如何将这些信息重新构建为人类可写笔划的子路径数组

(这里的想法是将点信息转换为新的类人笔划数据类型。这意味着需要一种算法来识别每个填充的起点、坡度、终点和边界)

提示

我在Pleco(一个成功实现了类似算法的iOS应用程序)中注意到,每个笔划都由描述人类可写笔划的闭合路径组成。UIBezierPath有一个基于连续连接填充的闭合路径。需要一个算法来细化重叠填充,为每个笔划创建不同的闭合路径

Erica Sadun在github上有一组可用的文件。我还没有完全研究过这些文件,但它们可能在确定离散笔划时很有用

UIBezierPath结构似乎基于连续线段/曲线的概念。在填充的交点处出现汇流点,表示方向路径变化。是否可以计算曲线/线段的笔划/填充角度,并搜索其他曲线/直线以查找相应的汇流点?(即,跨相交填充间隙连接一条线段,以生成两条单独的路径——假设其中一条拾取点并使用新线段/曲线重新创建路径)

反省一下:有没有更简单的方法?我是否缺少一个关键的API、一本书或一个更好的方法来解决这个问题

产生预期结果的一些替代方法(无效-需要加载GIF或flash):

有一个表示层,显示书写笔划的进展。(如果可能的话,这就是我希望在Swift/iOS中的近似值)-(-参见左侧的动画图像)

显示使用渐进路径和填充近似书写笔划特征(动画不平滑,需要外部资源):

-我熟悉创建Flash动画,但我不愿意在1000年代实现这些动画(更不用说它在iOS上不受支持,尽管我可能还可以转换一种算法来利用HTML5画布和css动画)但这条思路似乎有点遥远,毕竟,我想要的路径信息存储在我从提供的字体/字符串中提取的字形中

方法2

我正在考虑使用字体而不是字体来获得正确的路径信息(即填充表示为路径的信息)。如果成功,这种方法将比近似笔划、笔划类型、交叉点和笔划顺序更简洁。我已经向苹果公司提交了一份雷达报告,建议将基于笔划的字体添加到iOS(#20426819).尽管做出了这些努力,我仍然没有放弃形成一个算法,从贝塞尔路径上的线段和曲线解析部分笔划、完整笔划、交点和汇合点

根据讨论/回答更新想法

以下附加信息是根据下面正在进行的对话和回答提供的

笔画顺序很重要,大多数语言(本例中为中文)都有明确的定义,并且