iOS上具有不对称形状的核心文本

iOS上具有不对称形状的核心文本,ios,quartz-2d,core-text,Ios,Quartz 2d,Core Text,我想写一个路径,可以采取任何形状的文字。现在我可以在其中绘制翻转的文本: NSArray *coordinates = ...; CGMutablePathRef pathRef = [self objectPathGivenCoordinates:coordinates]; ... // Draw the shapes // Now draw the text CGContextSetTextMatrix(context, CGAffineTransformIdentity);

我想写一个路径,可以采取任何形状的文字。现在我可以在其中绘制翻转的文本:

NSArray *coordinates = ...;

CGMutablePathRef pathRef = [self objectPathGivenCoordinates:coordinates];

... // Draw the shapes

// Now draw the text    
CGContextSetTextMatrix(context, CGAffineTransformIdentity);

NSAttributedString* attString = [[NSAttributedString alloc] initWithString:@"0,1,2..."];
CTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)attString);
CTFrameRef frame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, [attString length]), pathRef, NULL);
CTFrameDraw(frame, context);
这就产生了:

我知道iOS有一个翻转的坐标系。大多数解决方案在绘制前添加这两条线:

CGContextTranslateCTM(context, 0, rect.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
但这就产生了:

那么为什么这项技术不起作用呢?在我所看到的每个示例中,当文本以某种对称形式呈现时,或使用剪切,或在OS X上呈现时,都会使用此技术。如果我们以对称形状绘制文本,则调用
CGContextTranslateCTM()
CGContextScaleCTM()
是有意义的。调用
cgcontexttranslatecm(context,0,rect.size.height)
,将第一个字母的原点移到顶部。调用
CGContextScaleCTM(context,1,-1)
会反转Y的方向。如果我们在对称形状上反转Y的方向,它不会改变。遗憾的是,我的形状不是对称的

这是我考虑过但放弃的东西

  • 在同一比例上绘制形状和数字(两个都倒置),然后将
    UIImageView
    以某种方式翻转到其后面(1)
  • 不要打电话更改比例或翻译CTM。使用
    CGContextSetTextMatrix()
    翻转文本矩阵,使文本从左向右、从下至上、从右向上绘制。确定形状的字符串后,确定形状中剩余的额外字符数。反转单词(现在它将从上到下、从右到左、从右到上)。为每个额外字符添加空格。现在,对于每个
    CTLine
    ,以某种方式再次反转单词(现在它将从上到下、从左到右、从右到上)(2)
我为什么抛弃他们

(1) 我不能翻转我的图像。它们总是需要正面朝上


(2) 对于一个别人知道的简单解决方案来说,这可能有些过分了

我决定了一个解决方案

// Flip the coordinates so that the object is drawn as if it were mirrored along the x-axis
// coordinates = @[CGPointMake(1, 2), CGPointMake(9, 17), CGPointMake(41, 3), ...]
NSArray *flippedCoordinates = [coordinates map:^id(id object) {
     CGPoint value;
     [object getValue:&value];
     CGPoint point = value;

     point.y = point.y * (-1) + rect.size.height;

     return [NSValue value:&point withObjCType:@encode(CGPoint)];
}];

// Generate a CGPathRef using the new coordinates
CGMutablePathRef pathRef = CGPathCreateMutable();
CGPathMoveToPoint(pathRef, NULL, [[flippedCoordinates objectAtIndex:0] CGPointValue].x + .5 [[flippedCoordinates objectAtIndex:0] CGPointValue].y + .5);
for(NSValue *arrayValue in flippedCoordinates) {
    CGPoint point = [arrayValue CGPointValue];
    CGPathAddLineToPoint(pathRef, NULL, point.x, point.y);
}
CGPathCloseSubpath(pathRef);

// Draw the object
// ...

// Draw the text as if it were on OS X
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
NSAttributedString* attString = [[NSAttributedString alloc] initWithString:@"0,1,2,..." attributes:@{(NSString *)kCTForegroundColorAttributeName : textColor}];
CTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)attString);
CTFrameRef frame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, [attString length]), pathRef, NULL);
CTFrameDraw(frame, context);

CFRelease(frame);
CFRelease(frameSetter);
CFRelease(pathRef);

// And, for the magic touch, flip the whole view AFTER everything is drawn
[self.layer setAffineTransform:CGAffineTransformMakeScale(1, -1)];
现在一切都是从上到下,从左到右,从右到上绘制的


使用
CGContextSetTextMatrix(上下文,CGAffineTransformMakeScale(1,-1))
代替cgAffineTransformIdentity请参见问题末尾的第二个考虑事项