Resize CATextLayer to fit text on iOS

后端 未结 4 1785
囚心锁ツ
囚心锁ツ 2020-12-29 05:01

All my research so far seems to indicate it is not possible to do this accurately. The only two options available to me at the outset were:

a) Using a La

相关标签:
4条回答
  • 2020-12-29 05:37

    Try this:

    - (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;
    }
    

    You'll have to convert your NSString to NSAttributedString. In-case of CATextLayer, you can use following CATextLayer subclass method:

    - (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.

    0 讨论(0)
  • 2020-12-29 05:48

    With LabelKit you don't need CATextLayer anymore. No more wrong line spacing and wider characters, all is drawn in the same way as UILabel does, while still animated.

    0 讨论(0)
  • 2020-12-29 06:00

    I have a much easier solution, that may or may not work for you.

    If you aren't doing anything special with the CATextLayer that you can't do a UILabel, instead make a CALayer and add the layer of the UILabel to the 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
    
    0 讨论(0)
  • 2020-12-29 06:01

    This page gave me enough to create a simple centered horizontally CATextLayer : http://lists.apple.com/archives/quartz-dev/2008/Aug/msg00016.html

    - (void)drawInContext:(CGContextRef)ctx {
      CGFloat height, fontSize;
    
      height = self.bounds.size.height;
      fontSize = self.fontSize;
    
      CGContextSaveGState(ctx);
      CGContextTranslateCTM(ctx, 0.0, (fontSize-height)/2.0 * -1.0);
      [super drawInContext:ctx];
      CGContextRestoreGState(ctx);
    }
    
    0 讨论(0)
提交回复
热议问题