- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我有与 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, 0, 1, 0);
textLayer_.transform = CATransform3DRotate(textLayer_.transform, M_PI, 0, 1, 0);
[textLayer_ setNeedsDisplay];
为了测试,我在初始化期间分别旋转了文本。
// init text
textLayer_ = [CATextLayer layer];
…
textLayer_.transform = CATransform3DRotate(textLayer_.transform, M_PI, 0, 1, 0);
textLayer_.contentsScale = [[UIScreen mainScreen] scale];
文本可以旋转并保持清晰
图片 here
最佳答案
这里可能发生的事情是它决定必须将 textLayer 渲染为像素。注意 shouldRasterize in the CALayer Class Reference 的警告:
When the value of this property is NO, the layer is composited directly into the destination whenever possible. The layer may still be rasterized prior to compositing if certain features of the compositing model (such as the inclusion of filters) require it.
因此,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, M_PI, 0, 1, 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, 1, 0);
self.textLayerFront.transform = CATransform3DRotate(self.textLayerFront.transform, angle, 0, 1, 0);
self.textLayerBack.transform = CATransform3DRotate(self.textLayerBack.transform, angle, 0, 1, 0);
然后您应该会发现,您可以将标牌旋转到任意角度,同时文字保持清晰。
如果您真的需要以导致 CATextLayer 栅格化的方式来操纵文本显示,还有一个替代方法:将文本转换为 UIBezierPath
表示。然后可以将其放置在 CAShapeLayer 中。这样做需要深入研究 Core Text,但结果是强大的。例如,您可以 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, [font pointSize], 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, CFRangeMake(0, 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, CFRangeMake(0, 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, -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 旋转后文本模糊,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10152574/
我有几个 CATextLayers。当我双击其中之一时,我希望能够编辑它的字符串。想象一下在 Keynote 或许多其他应用程序中处理文本的方式。有什么想法吗? 我想在图层前面放置一个可编辑的文本字段
我在 CATextLayer 中绘制字符时遇到问题,使得图层的大小恰好等于字符的大小。 我使用下面的代码来获取与字符串中的字符对应的字形的大小。目前我忽略了变音符号,因此我假设字形和字符之间存在一对一
我已经束手无策了。我已经尝试了我认为的消除 CATextLayer 模糊的一切方法,但无济于事。诚然,有些东西是有帮助的,但是当放大 2 倍时,文本仍然太模糊,远不及非 CATextLayer 文本的
这让我发疯。每当我更改CATextLayer.foregroundColor属性的值时,无论我做什么,该更改都是动画的。例如,我有一个称为CATextLayer的layer,它是CALayer的子层s
我在使用 CATextLayer 时遇到了一些麻烦,这可能是我造成的,但我没有找到有关此主题的任何帮助。我在 OS X 上(在 iOS 上应该是一样的)。 我创建了一个比例因子 > 1 的 CATex
我有一个具有动态长度的动态字符串。我使用 CATextlayer 在 View 中绘制它。我设置了 wrapped = YES,但我不知道如何检查 View 中 CATextlayer 的行数来为另一
我正在开发一个需要更改 很多 CATextLayers 字符串的应用程序,但是,只有其中的一个或两个字符(但一般来说,字符串的长度约为 2-5字符)。 起初我使用的 UILabels 非常慢,因此我尝
我有一个带有 CATextLayer 子层的 CALayer。当我应用变换或以其他方式调整 CALayer 的大小时,我需要 CATextLayer 在其父级的边界内调整大小。调整大小时,CAText
我想使用 CATextLayer 以 NSAttributedString 的形式显示一些部分加粗的文本 - 但仍然想使用 IB 的便利性进行定位。 有没有办法通过界面生成器放入 CATextLaye
我正在尝试构建一个自定义控件,它可能看起来像这个 Inkscape 模型: 我正在使用 drawRect() 做一些事情,但我需要为一些元素设置动画,所以我决定切换到 CALayer 的组合。我一直在
上图显示了一个红色的 CATextLayer 框架。 当我增加文本字体大小时,文本超出框架。 我正在使用捏合手势来增加字体大小。我想获取 CATextLayer 中文本的大小,以便在文本框架超出图层框
我正在尝试将 CATextLayer 添加到 UITableViewCell。问题是文本呈现为黑色,而我已经设置了它的 foregroundColor。有人能告诉我我错过了什么吗?谢谢。 CAText
如果我包装了 == YES,有没有办法让 CATextLayer 显示“...”? 最佳答案 是的,设置 truncationMode = kCATruncationEnd。它默认为 kCATrunc
这应该真的有效,但不是: CATextLayer* textLayer = [CATextLayer layer]; textLayer.string = @"text"; [textLayer se
我有与 question 相关的问题 我设置了 contentsScale 之后,文本看起来不错,但如果我应用 3d 旋转变换,文本就会变得模糊。 图片 here 初始化代码 // init
我希望我的文本被白色边框包围。我正在使用 CATextLayer 作为文本。我知道 CATextLayer 没有属性 borderColor/borderWidth。当然,我可以使用它的父类(supe
我正在尝试修改图层中文本的字体属性,但没有成功。有人可以帮忙吗?请在下面找到代码: - (id)initWithFrame:(CGRect)frame { self = [super init
我想为我的图像创建一个文本叠加层。问题是,如果我尝试添加第二个文本,比如字幕,它会忽略我的字体大小。 titleLayer.frame = CGRectMake(0, 80, imageVie
我正在尝试对 CATextLayer 的字符串属性进行动画处理,以便我可以使用 AV Foundation 在我的视频中添加时间戳。有谁知道如何设置动画以便我可以每秒更改字符串值? 最佳答案 NSSt
我想画一个这样的列表: 1. List item 1 2. List item 2 3. List item 3 这是我的代码: NSTextList *list = [[NSTextList
我是一名优秀的程序员,十分优秀!