Update attributedText on a dequeued cell UITextView make the app freeze

204 Views Asked by At

I'm currently stuck down a big wall...

I'm using custom UITableViewCell containing UITextView containing custom NSTextAttachment images.

Each NSTextAttachment overrides the

 - (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)textContainer proposedLineFragment:(CGRect)lineFrag glyphPosition:(CGPoint)position characterIndex:(NSUInteger)charIndex;

and

- (UIImage *)imageForBounds:(CGRect)imageBounds
              textContainer:(NSTextContainer *)textContainer
             characterIndex:(NSUInteger)charIndex;

from the NSTextAttachmentContainer protocol.

The goal here is to display images with different sizes and adapt the bounds to the available space.

I also need to compute the cell height using the sizeThatFits statement on a dedicated cell before caching it.

Everything just worked fine until today when I tried to list a particular series of contents.

When dequeuing an old cell to display a brand new, my app just freeze in the [_textView setAttributedString:myAttributedText]; statement ([NSATSTypesetter beginLineWithGlyphAtIndex:] in the stack).

I just tried everything to avoid recreating cells every times (which actually works) in vain.

Here's what I found:

  • The issue remains even if I "hard code" return the cell height values.
  • Changing NSTextAttachment bounds (and keeping the cells height) seems to make the bug disappear without any logic...
  • It's clearly a devil combination of content, because if I change the cell heights to make the dequeue occurs later, everything works fine. Actually the two cells involved both contains a text including just one image.
  • I looked at the - (void)prepareForReuse method and tried to reset the UITextView state, also in vain.
  • Re-creating a brand new UITextView each time the cell is dequeued seems to solve the problem.

Any idea? Do I need to know something essential about the dequeuing system or the NSTextAttachmentContainer protocol?

Many thanks in advance.

EDIT: The only thing I found to resolve this issue is to do that:

- (void)prepareForReuse
{
    [super prepareForReuse];

    // Reset text
    _contentTextView.attributedText = nil;
    [_contentTextView sizeToFit];
}

The sizeToFit statement is here really important!

0

There are 0 best solutions below