Ios4 调整CATextLayer的大小以适应iOS上的文本

Ios4 调整CATextLayer的大小以适应iOS上的文本,ios4,sizewithfont,catextlayer,Ios4,Sizewithfont,Catextlayer,到目前为止,我所有的研究似乎都表明不可能做到这一点。一开始我只有两个选择: a) 使用CATextLayer的布局管理器-从4.0开始在iOS上不可用 b) 使用sizeWithFont:constrainedToSize:lineBreakMode:并根据此处返回的大小调整CATextLayer的框架 备选方案(b)是最简单的办法,应该可行。毕竟,它与UILabels完美结合。但当我对CATextLayer应用相同的帧计算时,帧总是比预期的或需要的大一点 事实证明,CATextLayers和U

到目前为止,我所有的研究似乎都表明不可能做到这一点。一开始我只有两个选择:

a) 使用CATextLayer的布局管理器-从4.0开始在iOS上不可用

b) 使用sizeWithFont:constrainedToSize:lineBreakMode:并根据此处返回的大小调整CATextLayer的框架

备选方案(b)是最简单的办法,应该可行。毕竟,它与UILabels完美结合。但当我对CATextLayer应用相同的帧计算时,帧总是比预期的或需要的大一点

事实证明,CATextLayers和UILabels(相同字体和大小)中的行距是不同的。因此,sizeWithFont(其行距计算将与UILabels的行距计算相匹配)不会返回CATextLayers的预期大小。

通过使用UILabel打印与CATextLayer相同的文本并比较结果,可以进一步证明这一点。第一行中的文本完全重叠(字体相同),但CATextLayer中的行距比UILabel中的行距略短。(很抱歉,我现在无法上传截图,因为我已经拥有的截图包含机密数据,而且我目前没有时间制作一个样本项目来获得清晰的截图。我会在以后有时间的时候上传给后代)

这是一个奇怪的区别,但我认为可以通过为我在那里使用的NSAttributedString指定适当的属性来调整CATextLayer中的间距,但事实似乎并非如此。查看CFStringAttributes.h,我找不到一个与行距相关的属性

底线:

因此,在需要使用CATextLayer以适应其文本的情况下,似乎不可能在iOS上使用CATextLayer。我在这件事上是对的还是遗漏了什么

附言:

  • 我之所以想使用CATextLayer和NSAttributedString,是因为要显示的字符串在不同点的颜色不同。我想我不得不像往常一样手工绘制字符串了……当然,总是可以选择从sizeWithFont中修改结果以获得合适的行高

  • 稍微滥用“代码”标签以使文章更具可读性

  • 我不能用“CATextLayer”来标记这篇文章——令人惊讶的是,目前还没有这样的标记。如果有人有足够的声誉撞上了这篇文章,请贴上相应的标签


  • 这个页面给了我足够的时间来创建一个简单的水平居中CATextLayer:

    试试这个:

    - (CGFloat)boundingHeightForWidth:(CGFloat)inWidth withAttributedString:(NSAttributedString *)attributedString {
        CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString( (CFMutableAttributedStringRef) attributedString); 
        CGSize suggestedSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetter, CFRangeMake(0, 0), NULL, CGSizeMake(inWidth, CGFLOAT_MAX), NULL);
        CFRelease(framesetter);
        return suggestedSize.height;
    }
    
    您必须将NSString转换为NSAttributedString。在
    CATextLayer
    的情况下,可以使用以下
    CATextLayer
    子类方法:

    - (NSAttributedString *)attributedString {
    
        // If string is an attributed string
        if ([self.string isKindOfClass:[NSAttributedString class]]) {
            return self.string;
        }
    
        // Collect required parameters, and construct an attributed string
        NSString *string = self.string;
        CGColorRef color = self.foregroundColor;
        CTFontRef theFont = self.font;
        CTTextAlignment alignment;
    
        if ([self.alignmentMode isEqualToString:kCAAlignmentLeft]) {
            alignment = kCTLeftTextAlignment;
    
        } else if ([self.alignmentMode isEqualToString:kCAAlignmentRight]) {
            alignment = kCTRightTextAlignment;
    
        } else if ([self.alignmentMode isEqualToString:kCAAlignmentCenter]) {
            alignment = kCTCenterTextAlignment;
    
        } else if ([self.alignmentMode isEqualToString:kCAAlignmentJustified]) {
            alignment = kCTJustifiedTextAlignment;
    
        } else if ([self.alignmentMode isEqualToString:kCAAlignmentNatural]) {
            alignment = kCTNaturalTextAlignment;
        }
    
        // Process the information to get an attributed string
        CFMutableAttributedStringRef attrString = CFAttributedStringCreateMutable(kCFAllocatorDefault, 0);
    
        if (string != nil)
            CFAttributedStringReplaceString (attrString, CFRangeMake(0, 0), (CFStringRef)string);
    
        CFAttributedStringSetAttribute(attrString, CFRangeMake(0, CFAttributedStringGetLength(attrString)), kCTForegroundColorAttributeName, color);
        CFAttributedStringSetAttribute(attrString, CFRangeMake(0, CFAttributedStringGetLength(attrString)), kCTFontAttributeName, theFont);
    
        CTParagraphStyleSetting settings[] = {kCTParagraphStyleSpecifierAlignment, sizeof(alignment), &alignment};
        CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate(settings, sizeof(settings) / sizeof(settings[0]));
        CFAttributedStringSetAttribute(attrString, CFRangeMake(0, CFAttributedStringGetLength(attrString)), kCTParagraphStyleAttributeName, paragraphStyle);    
        CFRelease(paragraphStyle);
    
        NSMutableAttributedString *ret = (NSMutableAttributedString *)attrString;
    
        return [ret autorelease];
    }
    

    HTH.

    我有一个更简单的解决方案,它可能对您有效,也可能对您无效

    如果您没有对CATextLayer执行任何无法执行UILabel的特殊操作,请创建CALayer并将UILabel的层添加到CALayer

    UILabel*label = [[UILabel alloc]init];
    
    //Do Stuff to label
    
    CALayer *layer = [CALayer layer];
    
    //Set Size/Position
    
    [layer addSublayer:label.layer];
    
    //Do more stuff to layer
    

    有了它,您不再需要
    CATextLayer
    。不再有错误的行距和更宽的字符,所有字符都以与UILabel相同的方式绘制,同时仍处于动画状态。

    我刚刚遇到了这个问题。。。竞相回答。@All,如果不清楚,这个问题严格地说是关于垂直调整固定宽度的CATextLayer的大小,用于不同长度/属性的字符串。对不起,我认为这不能回答问题。问题是垂直调整CATextLayer的大小,以包装/适合任何字符串,而答案是垂直对齐-这也是一行文本。对不起,已经有一段时间了,我目前没有代码或时间来测试这一点。不过,我一定会在可能的时候回来看看。同时,如果其他人看到这个答案可以验证它是否有效,我会将它标记为“已回答”。6个月后,我终于再次遇到这个问题。:)解决方案奏效了。非常感谢穆斯塔法!!啊,看。正如我在问题的底部所指出的,我特别需要使用CATextLayers来实现其奇特的格式化功能。否则一个UILabel会做得很好。不管怎样,这个问题已经发布很久了,到目前为止唯一有希望的线索是@Mustafa的。可悲的是,我已经很久没机会尝试了。有人想要吗?
    UILabel*label = [[UILabel alloc]init];
    
    //Do Stuff to label
    
    CALayer *layer = [CALayer layer];
    
    //Set Size/Position
    
    [layer addSublayer:label.layer];
    
    //Do more stuff to layer