Подтвердить что ты не робот

Emojis возится с obj-c sizeWithFont math

В UITableView, который должен отображать длинный список чатовских разговоров, часто содержащих emojis, возникает ошибка расчета размера.

Моя проблема в том, что если строка имеет только правильную длину, и я использую sizeWithFont, я при первом измерении, используя sizeWithFont, получаю неправильную длину строки, вызывая "разлад строки".

Я предполагаю, что это потому, что строка ":-)" шире, чем значок смайлика.

Свидетельства можно увидеть здесь:

Using <code>SizeWithFont</code>

Теперь, в некоторых других стеках, некоторые утверждают, что sizeWithFont будет учитывать только строку, а не Emoji, которая для меня не имеет смысла, поскольку она правильна "в конце концов"...

Но вместо этого они предлагают использовать sizeToFit, поэтому я решил отложить его.

Using SizeToFit

Bam, тот же результат.

Кто-нибудь знает, как противостоять этому? Есть ли boolean, чтобы проверить, выполнено ли "Ярлык, обработанный emoji", поэтому я могу пропустить этот вызов?

Выполнение одной и той же строки дважды ничего не делает, кажется, что нужно отобразить представление, прежде чем sizeWithFont осознает свою ошибку.

Показанный столбец выполняется в сегменте - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath в пользовательской ячейке. Я могу реплицировать ошибку на совершенно регулярном UITableViewCell, так что, похоже, это не так.

4b9b3361

Ответ 1

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

}

Ответ 2

Спасибо @SergiSolanellas! Здесь версия, которая принимает атрибутString, сокращает метод, потому что текст и шрифт уже установлены.

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