Text garbled when using NSTextContainer/NSLayoutManager with UITextView

614 views Asked by At

I'm implementing paged text and so I'm using NSLayoutManager and NSTextContainer to create UITextViews for each page. The paging is working fine, but the text is garbled. When setting the same NSTextStorage on a vanilla UITextView it appears correct:

// In the class that creates the pages
...
self.textStorage = [[NSTextStorage alloc] initWithString:string attributes:@{}];
self.layoutManager.textStorage = self.textStorage;
....

- (void)createPages{
    // Remove all current text containers
    while (self.layoutManager.textContainers.count > 0){
        [self.layoutManager removeTextContainerAtIndex:0];
    }
    NSMutableArray *textContainers = [NSMutableArray array];
    NSUInteger lastRenderedGlyph = 0;
    while (lastRenderedGlyph < self.layoutManager.numberOfGlyphs){
        NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:self.pageSize];
        [self.layoutManager addTextContainer:textContainer];
        [textContainers addObject:textContainer];
        [self addDummyContainersForNewlinesAfterContainer:textContainer];
        NSRange range = [self.layoutManager glyphRangeForTextContainer:textContainer];
        lastRenderedGlyph = NSMaxRange(range);
    }
    self.textContainers = textContainers;
}

// In my ViewController
- (void)addTextViews{
    self.scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
    self.scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    self.scrollView.backgroundColor = [UIColor lightGrayColor];
    [self.view addSubview:self.scrollView];
    CGFloat xOffset = 0;
    // Option #1 - This results in garbled text
    for (NSTextContainer *textContainer in self.coordinator.textContainers){
        break;
        CGRect frame = CGRectMake(xOffset, 0, self.coordinator.pageSize.width, self.coordinator.pageSize.height);
        xOffset = CGRectGetMaxX(frame)+1;
        self.scrollView.contentSize = CGSizeMake(xOffset, self.coordinator.pageSize.width);
        UITextView *textView = [[UITextView alloc] initWithFrame:frame textContainer:textContainer];
        textView.attributedText = self.coordinator.textStorage;
        [self.scrollView addSubview:textView];
    }
    // Option #2 - This does not result in garbled text
    UITextView *textView = [[UITextView alloc] initWithFrame:self.view.bounds];
    [self.view addSubview:textView];
    textView.attributedText = self.coordinator.textStorage;
}

Good Text Bad Text

1

There are 1 answers

1
arsenius On BEST ANSWER

It turns out I had forgotten to add

    [self.textStorage addLayoutManager:self.layoutManager];

That fixes the issue.