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, так что, похоже, это не так.
Ответы
Ответ 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;
}