Skip to content

Commit

Permalink
Fixes /issues/6441 - Incorrect timeline item text height calculation (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanceriu authored Sep 6, 2022
1 parent d65143a commit 405c2d8
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 35 deletions.
63 changes: 28 additions & 35 deletions Riot/Modules/MatrixKit/Models/Room/MXKRoomBubbleCellData.m
Original file line number Diff line number Diff line change
Expand Up @@ -518,46 +518,39 @@ - (CGFloat)rawTextHeight: (NSAttributedString*)attributedText

- (CGSize)textContentSize:(NSAttributedString*)attributedText removeVerticalInset:(BOOL)removeVerticalInset
{
static UITextView* measurementTextView = nil;
static UITextView* measurementTextViewWithoutInset = nil;
if (attributedText.length == 0) {
return CGSizeZero;
}

if (attributedText.length)
// Grab the default textContainer insets and lineFragmentPadding from a dummy text view.
// This has no business being here but the refactoring effort would be too great (sceriu 05.09.2022)
static UITextView* measurementTextView = nil;
if (!measurementTextView)
{
if (!measurementTextView)
{
measurementTextView = [[UITextView alloc] init];

measurementTextViewWithoutInset = [[UITextView alloc] init];
// Remove the container inset: this operation impacts only the vertical margin.
// Note: consider textContainer.lineFragmentPadding to remove horizontal margin
measurementTextViewWithoutInset.textContainerInset = UIEdgeInsetsZero;
}

// Select the right text view for measurement
UITextView *selectedTextView = (removeVerticalInset ? measurementTextViewWithoutInset : measurementTextView);

selectedTextView.frame = CGRectMake(0, 0, _maxTextViewWidth, 0);
selectedTextView.attributedText = attributedText;

CGSize size = [selectedTextView sizeThatFits:selectedTextView.frame.size];

// Manage the case where a string attribute has a single paragraph with a left indent
// In this case, [UITextView sizeThatFits] ignores the indent and return the width
// of the text only.
// So, add this indent afterwards
NSRange textRange = NSMakeRange(0, attributedText.length);
NSRange longestEffectiveRange;
NSParagraphStyle *paragraphStyle = [attributedText attribute:NSParagraphStyleAttributeName atIndex:0 longestEffectiveRange:&longestEffectiveRange inRange:textRange];

if (NSEqualRanges(textRange, longestEffectiveRange))
{
size.width = size.width + paragraphStyle.headIndent;
}
measurementTextView = [[UITextView alloc] init];
}

CGFloat verticalInset = measurementTextView.textContainerInset.top + measurementTextView.textContainerInset.bottom;
CGFloat horizontalInset = measurementTextView.textContainer.lineFragmentPadding * 2;

CGSize size = [attributedText boundingRectWithSize:CGSizeMake(_maxTextViewWidth - horizontalInset, CGFLOAT_MAX)
options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
context:nil].size;

//In iOS 7 and later, this method returns fractional sizes (in the size component of the returned rectangle);
// to use a returned size to size views, you must use raise its value to the nearest higher integer using the
// [ceil](https://developer.apple.com/documentation/kernel/1557272-ceil?changes=latest_major) function.
size.width = ceil(size.width);
size.height = ceil(size.height);

return size;
// The result is expected to contain the textView textContainer's paddings. Add them back if necessary
if (removeVerticalInset == NO) {
size.height += verticalInset;
}

return CGSizeZero;
size.width += horizontalInset;

return size;
}

#pragma mark - Properties
Expand Down
1 change: 1 addition & 0 deletions changelog.d/6441.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fixed incorrect iOS 16 timeline item text height calculations leading to empty gaps.

0 comments on commit 405c2d8

Please sign in to comment.