iOS   发布时间:2022-03-30  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了ios – 旋转后的CATextLayer模糊文本大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我有question有关的问题
我已经设置了contentsScale并且在该文本看起来很好但是如果我应用3d旋转变换,则文本模糊不清.

图片here

初始化代码

// init text
    textLayer_ = [CATextLayer layer];
    …
    textLayer_.contentsScale = [[UIScreen mainScreen] scale];

    // init body path
    pathLayer_ = [CAShapeLayer layer];
    …
    [pathLayer_ addSublayer:textLayer_];

轮换代码

// make the mirror
    pathLayer_.transform = CATransform3DRotate(pathLayer_.transform,M_PI,1,0);
    textLayer_.transform = CATransform3DRotate(textLayer_.transform,0);
    [textLayer_ setNeedsDisplay];

为了测试我在初始化期间单独旋转文本.

// init text
    textLayer_ = [CATextLayer layer];
    …
    textLayer_.transform = CATransform3DRotate(textLayer_.transform,0);
    textLayer_.contentsScale = [[UIScreen mainScreen] scale];

文本可以旋转并保持清晰
图片here

解决方法

光栅化

这里可能发生的是它决定将textLayer渲染为像素.请注意0​​7000的警告:

因此,CATextLayer可能会突然决定进行栅格化.如果它是旋转图层的子图层,它决定栅格化.所以,不要让这种情况发生.

单面图层

这会将您带回导致反转文本的解决方案.您可以通过关闭文本图层上的doubleSided来防止这种情况.您的标志现在在远处是空白的,因此添加第二个文本图层,相对于第一个旋转180度.

声明两个文本图层:

@property (retain) CAShapeLayer *pathLayer;
@property (retain) CATextLayer *textLayerFront;
@property (retain) CATextLayer *textLayerBACk;

然后,将它们初始化为单面,背面层旋转180度:

CAShapeLayer *pathLayer = [CAShapeLayer layer];
// Also need to store a UIBezierPath in the pathLayer.

CATextLayer *textLayerFront = [CATextLayer layer];
textLayerFront.doubleSided = NO;
textLayerFront.String = @"Front";
textLayerFront.contentsScale = [[UIScreen mainScreen] scale];

CATextLayer *textLayerBACk = [CATextLayer layer];
textLayerBACk.doubleSided = NO;
// Eventually both sides will have the same text,but for demonstration purposes we will label them differently.
textLayerBACk.String = @"BACk";
// Rotate the BACk layer 180 degrees relative to the front layer.
textLayerBACk.transform = CATransform3DRotate(textLayerBACk.transform,0);
textLayerBACk.contentsScale = [[UIScreen mainScreen] scale];

// Make all the layers siblings.  these means they must all be rotated independently of each other.

// The layers can flicker if their Z position is close to the BACkground,so move them forWARD.
// This will not work if the main layer has a perspective transform on it.
textLayerFront.zPosition = 256;
textLayerBACk.zPosition = 256;

// It would make sense to make the text layers siblings of the path layer,but this seems to mean they get pre-rendered,blurring them.
[self.layer addSublayer:pathLayer];
[self.layer addSublayer:textLayerBACk];
[self.layer addSublayer:textLayerFront];

// Store the layers constructed at this time for later use.
[self setTextLayerFront:textLayerFront];
[self setTextLayerBACk:textLayerBACk];
[self setPathLayer:pathLayer];

然后,您可以旋转图层.只要您始终旋转相同的量,它们就会显示正确.

CGFloat angle = M_PI;
self.pathLayer.transform = CATransform3DRotate(self.pathLayer.transform,angle,0);
self.textLayerFront.transform = CATransform3DRotate(self.textLayerFront.transform,0);
self.textLayerBACk.transform = CATransform3DRotate(self.textLayerBACk.transform,0);

然后,您应该发现在文本保持清晰时可以将符号旋转到任意角度.

文本到路径

如果您确实需要以导致CATextLayer栅格化的方式操作文本显示,还有另一种选择:将文本转换为UIBezierPath表示.然后可以将其放在CAShapeLayer中.这样做需要深入研究核心文本,但结果是强大的.例如,你可以animate the text being drawn.

// - (UIBezierPath*) bezierPathWithString:(NSString*) String font:(UIFont*) font inRect:(CGRect) rect;
// requires CoreText.framework
// This creates a graphical version of the input screen,line wrapped to the input rect.
// Core Text involves a whole hierarchy of objects,all requiring manual management.
- (UIBezierPath*) bezierPathWithString:(NSString*) String font:(UIFont*) font inRect:(CGRect) rect;
{
    UIBezierPath *combinedGlyphsPath = nil;
    CGMutablePathRef combinedGlyphsPathRef = CGPathCreateMutable();
    if (combinedGlyphsPathRef)
    {
        // It would be easy to wrap the text into a different shape,including arbitrary bezier paths,if needed.
        UIBezierPath *frameShape = [UIBezierPath bezierPathWithRect:rect];

        // If the font name wasn't found while creaTing the font object,the result is a crash.
        // Avoid this by falling BACk to the system font.
        CTFontRef fontRef;
        if ([font fontName])
            fontRef = CTFontCreateWithName((__bridge CFStringRef) [font fontName],[font pointSize],null);
        else if (font)
            fontRef = CTFontCreateUIFontForLanguage(kCTFontUserFontType,null);
        else
            fontRef = CTFontCreateUIFontForLanguage(kCTFontUserFontType,[UIFont systemFontSize],null);

        if (fontRef)
        {
            CGPoint basePoint = CGPointMake(0,CTFontGetAscent(fontRef));
            CFStringRef keys[] = { kCTFontAttributename };
            CFTypeRef values[] = { fontRef };
            CFDictionaryRef attributesRef = CFDictionaryCreate(NULL,(const void **)&keys,(const void **)&values,sizeof(keys) / sizeof(keys[0]),&kcfTypeDictionaryKeyCallBACks,&kcfTypeDictionaryValueCallBACks);

            if (attributesRef)
            {
                CFAttributedStringRef attributedStringRef = CFAttributedStringCreate(NULL,(__bridge CFStringRef) String,attributesRef);

                if (attributedStringRef)
                {
                    CTFramesetterRef frameSetterRef = CTFramesetterCreateWithAttributedString(attributedStringRef);

                    if (frameSetterRef)
                    {
                        CTFrameRef frameRef = CTFramesetterCreateFrame(frameSetterRef,CFRangeMake(0,0),[frameShape CGPath],null);

                        if (frameRef)
                        {
                            CFArrayRef lines = CTFrameGetLines(frameRef);
                            CFIndex lineCount = CFArrayGetCount(lines);
                            CGPoint lineOrigins[lineCount];
                            CTFrameGetLineOrigins(frameRef,lineCount),lineOrigins);

                            for (CFIndex lineIndex = 0; lineIndex<lineCount; lineIndex++)
                            {
                                CTLineRef lineRef = CFArrayGetValueATindex(lines,lineIndeX);
                                CGPoint lineOrigin = lineOrigins[lineIndex];

                                CFArrayRef runs = CTLineGetGlyphRuns(lineRef);

                                CFIndex runCount = CFArrayGetCount(runs);
                                for (CFIndex runIndex = 0; runIndex<runCount; runIndex++)
                                {
                                    CTRunRef runRef = CFArrayGetValueATindex(runs,runIndeX);

                                    CFIndex glyphCount = CTRunGetGlyphCount(runRef);
                                    CGGlyph glyphs[glyphCount];
                                    CGSize glyphAdvances[glyphCount];
                                    CGPoint glyPHPositions[glyphCount];

                                    CFRange runRange = CFRangeMake(0,glyphCount);
                                    CTRunGetGlyphs(runRef,glyphCount),glyphs);
                                    CTRunGetPositions(runRef,runRange,glyPHPositions);

                                    CTFontGetAdvancesForGlyphs(fontRef,kCTFontDefaultOrientation,glyphs,glyphAdvances,glyphCount);

                                    for (CFIndex glyphIndex = 0; glyphIndex<glyphCount; glyphIndex++)
                                    {
                                        CGGlyph glyph = glyphs[glyphIndex];

                                        // For regular UIBezierPath drawing,we need to invert around the y axis.
                                        CGAffineTransform glyphTransform = CGAffineTransformMakeTranslation(lineOrigin.x+glyPHPositions[glyphIndex].x,rect.size.height-lineOrigin.y-glyPHPositions[glyphIndex].y);
                                        glyphTransform = CGAffineTransformScale(glyphTransform,-1);

                                        CGPathRef glyPHPathRef = CTFontCreatePathForGlyph(fontRef,glyph,&glyphTransform);
                                        if (glyPHPathRef)
                                        {
                                            // Finally carry out the appending.
                                            CGPathAddPath(combinedGlyphsPathRef,NULL,glyPHPathRef);

                                            CFRelease(glyPHPathRef);
                                        }

                                        basePoint.x += glyphAdvances[glyphIndex].width;
                                        basePoint.y += glyphAdvances[glyphIndex].height;
                                    }
                                }
                                basePoint.x = 0;
                                basePoint.y += CTFontGetAscent(fontRef) + CTFontGetDescent(fontRef) + CTFontGetLeading(fontRef);
                            }

                            CFRelease(frameRef);
                        }

                        CFRelease(frameSetterRef);
                    }
                    CFRelease(attributedStringRef);
                }
                CFRelease(attributesRef);
            }
            CFRelease(fontRef);
        }
        // CasTing a CGMutablePathRef to a CGPathRef seems to be the only way to convert what was just built into a UIBezierPath.
        combinedGlyphsPath = [UIBezierPath bezierPathWithCGPath:(CGPathRef) combinedGlyphsPathRef];

        CGPathRelease(combinedGlyphsPathRef);
    }
    return combinedGlyphsPath;
}

这是旋转的轮廓文本,使用上面的方法创建.还可以在没有文本层的z位置变得明显的情况下添加透视.

大佬总结

以上是大佬教程为你收集整理的ios – 旋转后的CATextLayer模糊文本全部内容,希望文章能够帮你解决ios – 旋转后的CATextLayer模糊文本所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。