Text offset of MLEmojiLabel and TTTAttributedLabel

Posted by doodmon on Fri, 13 Dec 2019 19:25:01 +0100

When making a view of floating layer rolling chat, MLEmojiLabel and TTTAttributedLabel are used as three-party open-source files. The problems encountered are: 1. According to the demo of MLEmojiLabel, add emojiLabel to the content view of tableView, and find that emojiLabel will always be about 5pt lower. 2. With the increase of text, the lower the degree is, and the calculated cell height is higher.

Found three documents, found this place:

- (CGRect)textRectForBounds:(CGRect)bounds
     limitedToNumberOfLines:(NSInteger)numberOfLines
{
    bounds = UIEdgeInsetsInsetRect(bounds, self.textInsets);
    if (!self.attributedText) {
        return [super textRectForBounds:bounds limitedToNumberOfLines:numberOfLines];
    }

    CGRect textRect = bounds;

    // Calculate height with a minimum of double the font pointSize, to ensure that CTFramesetterSuggestFrameSizeWithConstraints doesn't return CGSizeZero, as it would if textRect height is insufficient.
    textRect.size.height = MAX(self.font.lineHeight * MAX(2, numberOfLines), bounds.size.height);

    // Adjust the text to be in the center vertically, if the text size is smaller than bounds
    CGSize textSize = CTFramesetterSuggestFrameSizeWithConstraints([self framesetter], CFRangeMake(0, (CFIndex)[self.attributedText length]), NULL, textRect.size, NULL);
    textSize = CGSizeMake(CGFloat_ceil(textSize.width), CGFloat_ceil(textSize.height)); // Fix for iOS 4, CTFramesetterSuggestFrameSizeWithConstraints sometimes returns fractional sizes

    if (textSize.height < bounds.size.height) {
        CGFloat yOffset = 0.0f;
        switch (self.verticalAlignment) {
            case TTTAttributedLabelVerticalAlignmentCenter:
                yOffset = CGFloat_floor((bounds.size.height - textSize.height) / 2.0f);
                break;
            case TTTAttributedLabelVerticalAlignmentBottom:
                yOffset = bounds.size.height - textSize.height;
                break;
            case TTTAttributedLabelVerticalAlignmentTop:
            default:
                break;
        }

        textRect.origin.y += yOffset;
    }

    return textRect;
}

In this place, yOffset of emojiLabel is recalculated according to verticalAlignment. If TTTAttributedLabelVerticalAlignmentCenter and TTTAttributedLabelVerticalAlignmentBottom are used, yOffset will increase. There is not much time to study why TT does this, but it is the problem caused here.

There are two modifications in MLEmojiLabel: 1. In the method of calculating cell height, use emojiLabel.verticalAlignment = TTTAttributedLabelVerticalAlignmentTop when creating static emojiLabel; 2. Use TTTAttributedLabelVerticalAlignmentTop when creating emojiLabel in your own cell. Using TTTAttributedLabelVerticalAlignmentTop will no longer recalculate the yOffset of emojiLabel.

Topics: Mobile iOS