iOS上具有不对称形状的核心文本 [英] Core Text With Asymmetric Shape on iOS

查看:96
本文介绍了iOS上具有不对称形状的核心文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在可以占用任何形状的路径中书写文字。现在我可以在其中绘制翻转文本:

I want to write text in a path that can take up any shape. Right now I can draw flipped text in it:

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有一个翻转坐标系。大多数解决方案在绘制之前添加这两行:

I understand that iOS has a flipped coordinate system. Most solutions add these two lines before drawing:

CGContextTranslateCTM(context, 0, rect.size.height);
CGContextScaleCTM(context, 1.0, -1.0);

但这产生了这个:

< img src =https://i.stack.imgur.com/up7UW.pngalt =文字现在写成左右右上方但超出路径边界>

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

So why doesn't this technique work? In every example I've seen, this technique is used when text is rendered in something symmetric, or with clipping, or on OS X. If we're drawing text in a symmetric shape, our calls to CGContextTranslateCTM() and CGContextScaleCTM() make sense. A call to CGContextTranslateCTM(context, 0, rect.size.height), moves the origin of the first letter to the top. A call to CGContextScaleCTM(context, 1, -1) reverses the direction of Y. If we reverse the direction of Y on a symmetric shape, it doesn't change. Sadly, my shapes aren't symmetric.

这是我考虑但放弃了


  • 以相同比例绘制形状和数字(均为倒置),然后以某种方式翻转 UIImageView (1)

  • 不要拨打电话来改变比例或翻译CTM。使用 CGContextSetTextMatrix()翻转文本矩阵,以便从左到右,从下到上,并且正面朝上绘制文本。确定在确定形状的字符串后,形状中剩余多少个额外字符。翻转单词(现在它将从上到下,从右到左,右上方)。为每个额外的角色添加空格。现在每个 CTLine ,以某种方式再次反转单词(现在它将从上到下,从左到右,右上方)(2)

  • Draw shapes and numbers on the same scale (both upside-down), then flip the UIImageView behind it somehow (1)
  • Don't make calls to change the scale or translate the CTM. Flip the text matrix with CGContextSetTextMatrix() so that text is drawn from left to right, bottom up, and is right side up. Determine how many extra characters are left in the shape after a string for the shape is determined. Reverse the words (now it will draw top to bottom, right to left, right side up). Add spaces for every extra character. Now for each CTLine, somehow reverse the words again (now it will draw top to bottom, left to right, right side up) (2)

为什么我抛弃它们

(1)我无法翻转图像。他们总是需要正面朝上

(1) I can't flip my images. They always need to be right side up

(2)对于其他人都知道的简单解决方案,这可能有点过分

(2) This may be overkill for a simple solution someone else knows

推荐答案

我确定了一个解决方案

// 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)];

现在一切都是从上到下,从左到右,右上方绘制的

Now everything is drawn from top to bottom, left to right, right side up

这篇关于iOS上具有不对称形状的核心文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆