2

CATextLayer を作成して UIView に描画するこのコードがあります。

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    CGRect viewRect = CGRectMake(50.0f, 50.0f, 345.0f, 120.0f);

    CATextLayer *textLayer = [CATextLayer layer];
    textLayer.contentsScale = [[UIScreen mainScreen] scale];
    textLayer.wrapped = YES;
    textLayer.truncationMode = kCATruncationNone;
    UIFont *font = [UIFont fontWithName:@"SnellRoundhand" size:20.0f];
    textLayer.string = @"Lorem Lipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.";
    textLayer.alignmentMode = kCAAlignmentLeft;
    textLayer.fontSize = font.pointSize;
    CTFontRef fontRef = CTFontCreateWithName((__bridge CFStringRef)font.fontName, font.pointSize, nil);
    textLayer.font = fontRef;
    CFRelease(fontRef);

    textLayer.backgroundColor = [[UIColor lightGrayColor] CGColor];
    textLayer.foregroundColor = [[UIColor blackColor] CGColor];
    textLayer.frame = viewRect;


    UIGraphicsBeginImageContextWithOptions(textLayer.frame.size, NO, 0);
    [textLayer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *textImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    UIImageView *textImageView = [[UIImageView alloc] initWithImage:textImage];
    textImageView.frame = viewRect;
    [self.view addSubview:textImageView];
}

残念ながら、ビューをレンダリングするときに一部の文字が切り取られます。私が投稿した例では、最初の「L」の左端のピクセルが欠落しており、2 番目の最後の「d」の右端のピクセルが欠落しています。

テキストの折り返し方法を変更せずに、このカットオフが発生しないようにする方法はありますか?

4

1 に答える 1

1

CATextLayerのデフォルトの動作を使用する代わりに、CATextLayerからデータを取得し、それを手動でCGContextに描画する関数を作成しました。カットオフの問題を処理するために、パディングのパラメーターを追加しました。

-(UIImage *)imageFromCATextLayer:(CATextLayer *)layer andPaddingSize:(CGSize)paddingSize
{
    CGFloat paddingWidth = paddingSize.width;
    CGFloat paddingHeight = paddingSize.height;
    CGRect textBounds = layer.frame;
    CGRect paddedImageBounds = CGRectMake(0.0f, 0.0f, textBounds.size.width + 2 * paddingWidth, textBounds.size.height + 2 * paddingHeight);
    UIGraphicsBeginImageContextWithOptions(paddedImageBounds.size, NO, 0);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextTranslateCTM(context, 0.0f, paddedImageBounds.size.height);
    CGContextScaleCTM(context, 1, -1);

    CGContextSetFillColorWithColor(context, layer.backgroundColor);
    CGContextFillRect(context, paddedImageBounds);

    CTTextAlignment alignment;
    if ([layer.alignmentMode isEqualToString: kCAAlignmentLeft]) {
        alignment = kCTLeftTextAlignment;
    }
    else if ([layer.alignmentMode isEqualToString: kCAAlignmentCenter]) {
        alignment = kCTCenterTextAlignment;
    }
    else if ([layer.alignmentMode isEqualToString: kCAAlignmentRight]) {
        alignment = kCTRightTextAlignment;
    }
    else {
        alignment = kCTLeftTextAlignment;
    }

    CTParagraphStyleSetting paragraphSettings = {kCTParagraphStyleSpecifierAlignment, sizeof(alignment), &alignment};
    CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate(&paragraphSettings, 1);

    NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:layer.font, (NSString*)kCTFontAttributeName, paragraphStyle, kCTParagraphStyleAttributeName, layer.foregroundColor, kCTForegroundColorAttributeName, nil];
    NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:layer.string attributes:attributes];
    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((__bridge_retained CFAttributedStringRef)attrString);
    CGMutablePathRef p = CGPathCreateMutable();
    CGPathAddRect(p, NULL, CGRectMake(10.0f, 2 * paddingHeight - 10.0f, textBounds.size.width, textBounds.size.height));
    CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0,0), p, NULL);
    CTFrameDraw(frame, context);

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}
于 2012-08-03T21:30:27.733 に答える