Emojis messing with obj-c's sizeWithFont math

前端 未结 3 679
青春惊慌失措
青春惊慌失措 2021-02-01 07:10

In a UITableView that needs to display a long list of chatlike conversations, often containing emojis, a size calculation error occurs.

My problem is, that

相关标签:
3条回答
  • 2021-02-01 07:36

    Thank you @SergiSolanellas! Here's a version that takes an attributedString, shortening the method because the text and font are already set.

    //
    // Given an attributed string that may have emoji characters and the width of 
    // the display area, return the required display height.
    //
    - (CGFloat)heightForAttributedStringWithEmojis:(NSAttributedString *)attributedString forWidth:(CGFloat)width {
        CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attributedString);
        CFRange fitRange;
        CGSize frameSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetter, CFRangeMake(0, 0), NULL, CGSizeMake(width, CGFLOAT_MAX), &fitRange);
    
        CFRelease(framesetter);
    
        return frameSize.height;
    }
    
    0 讨论(0)
  • 2021-02-01 07:38
    - (CGFloat)heightStringWithEmojis:(NSString*)str fontType:(UIFont *)uiFont ForWidth:(CGFloat)width {
    
    // Get text
    CFMutableAttributedStringRef attrString = CFAttributedStringCreateMutable(kCFAllocatorDefault, 0);
    CFAttributedStringReplaceString (attrString, CFRangeMake(0, 0), (CFStringRef) str );
    CFIndex stringLength = CFStringGetLength((CFStringRef) attrString);
    
    // Change font
    CTFontRef ctFont = CTFontCreateWithName((__bridge CFStringRef) uiFont.fontName, uiFont.pointSize, NULL);
    CFAttributedStringSetAttribute(attrString, CFRangeMake(0, stringLength), kCTFontAttributeName, ctFont);
    
    // Calc the size
    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(attrString);
    CFRange fitRange;
    CGSize frameSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetter, CFRangeMake(0, 0), NULL, CGSizeMake(width, CGFLOAT_MAX), &fitRange);
    
    CFRelease(ctFont);
    CFRelease(framesetter);
    CFRelease(attrString);
    
    return frameSize.height + 10;
    
    }
    
    0 讨论(0)
  • 2021-02-01 07:42

    I am use UILabel

    sizeThatFits(_ size: CGSize) -> CGSize

    It work for me.

    my code

    let tempLabel = UILabel()
    tempLabel.font = font
    tempLabel.attributedText = attText
    tempLabel.numberOfLines = 0
    let size = tempLabel.sizeThatFits(CGSize(width: 200, height:CGFloat.greatestFiniteMagnitude))
    

    as the code, you need to assign three property.

    0 讨论(0)
提交回复
热议问题