objective-c - 在 QuartzCore 中沿路径绘制文本

标签 objective-c cocoa-touch uiview core-graphics quartz-graphics

假设我有一个点数组,这些点形成一条线和一个文本。我怎样才能沿着这条线绘制文本

 - (void)drawRect:(CGRect)rect 

一个 UIView?

我可以毫无问题地绘制路径。是否有我忽略的标准方法或允许我沿着该路径绘制文本的框架?理想情况下,我想只使用 QuartzCore/CoreGraphics 来做到这一点。

我尝试计算每个字符的宽度并旋转每个字符。这种方法可行,但我想知道是否有更优雅的方法。

最佳答案

我相信您可以在 Mac OS X 中执行此操作,但在 iPhone 上最接近的是 CGContextShowGlyphsWithAdvances,它甚至不会旋转。

使用循环并使用类似以下内容绘制每个字符应该不会太难。这是改编自 Apple 的文档且未经测试,因此请注意:

CGContextSelectFont(myContext, "Helvetica", 12, kCGEncodingMacRoman);
CGContextSetCharacterSpacing(myContext, 10);
CGContextSetTextDrawingMode(myContext, kCGTextFillStroke);
CGContextSetRGBFillColor(myContext, 0, 0, 0, 1);
CGContextSetRGBStrokeColor(myContext, 0, 0, 0, 1);

NSUInteger charIndex = 0;
for(NSString *myChar in arrayOfChars) {
    char *cString = [myChar UTF8String];
    CGPoint charOrigin = originForPositionAlongPath(charIndex, myPath);
    CGFloat slope = slopeForPositionAlongPath(charIndex, myPath);

    CGContextSetTextMatrix(myContext, CGAffineTransformMakeRotation(slope));
    CGContextShowTextAtPoint(myContext, charOrigin.x, charOrigin.y, cString, 1);
}

编辑:这是 PositionAlongPath 函数的概念。同样,它们没有经过测试,但应该接近。 originAlong...如果您用完路径,则返回 (-1, -1)。

CGPoint originForPositionAlongPath(int index, NSArray *path) {
    CGFloat charWidth = 12.0;
    CGFloat widthToGo = charWidth * index;

    NSInteger i = 0;
    CGPoint position = [path objectAtIndex:i];

    while(widthToGo >= 0) {
            //out of path, return invalid point
        if(i >= [path count]) {
            return CGPointMake(-1, -1);
        }

        CGPoint next = [path objectAtIndex:i+1];

        CGFloat xDiff = next.x - position.x;
        CGFloat yDiff = next.y - position.y;
        CGFloat distToNext = sqrt(xDiff*xDiff + yDiff*yDiff);

        CGFloat fracToGo = widthToGo/distToNext
            //point is before next point in path, interpolate the answer
        if(fracToGo < 1) {
            return CGPointMake(position.x+(xDiff*fracToGo), position.y+(yDiff*fracToGo));
        }

            //advance to next point on the path
        widthToGo -= distToNext;
        position = next;
        ++i;
    }
}


CGFloat slopeForPositionAlongPath(int index, NSArray *path) {
    CGPoint begin = originForPositionAlongPath(index, path);
    CGPoint end = originForPositionAlongPath(index+1, path);

    CGFloat xDiff = end.x - begin.x;
    CGFloat yDiff = end.y - begin.y;

    return atan(yDiff/xDiff);
}

关于objective-c - 在 QuartzCore 中沿路径绘制文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2067166/

相关文章:

ios - 文件没有写入文档目录?

iphone - UIView autoresizingmask 不适合我

ios - UIView 子类未收到 NSNotificationCenter 通知

objective-c - 使用 NSData 在 NSTextView 中设置文本

ios - HTTP Post 中的大尺寸图像问题

objective-c - 在 obj-c 应用程序中将 appengine blob 用于二进制数据

ios - 带预览的分页 UIImages

ios - 使用多行contentView时accessoryView的对齐方式

iphone - 将值附加到 NSMutableArray 并保存到 NSUserDefaults

ios - 如何顺利移动 UIImageViews 数组?