UIPageViewController / TextKit Переформатирование текста при подкачке
Я работаю над многостраничным приложением для чтения, поддерживаемым TextKit, на основе сеанса «Расширенные макеты текста и эффекты с помощью Text Kit» из WWDC 2013 (но с некоторым кодом, восстановленным из неполного примера). Основная структура состоит в том, что вы рассчитываете количество страниц, необходимых для вашего текста, затем создаете NSTextContainer для каждой страницы и добавляете его в NSLayoutManager. Всякий раз, когда UIPageViewController запрашивает следующую или предыдущую страницу, вы создаете новый UITextView и устанавливаете его контейнер текста для текста, выбирая правильный из массива NLayoutManger NSTextContainers.
К сожалению, у меня есть проблема, когда текст перекрашивается как на первой странице, так и при первом возврате страницы на любую заданную страницу. Вот как это выглядит:
Это не самый яркий эффект (если вы его пропустили, обратите внимание на верхнюю часть экрана при переходе назад), но это немного дезориентирует, и я хотел бы устранить его, если это возможно. Учитывая, что текстовые контейнеры должны быть рассчитаны заранее, я не понимаю, почему он переформатирует текст или как его предотвратить. Кто-нибудь знает в чем проблема?
РЕДАКТИРОВАТЬ: Добавление примера кода.
@interface ReaderViewController () <UIPageViewControllerDataSource>
@property (nonatomic, assign) NSUInteger numberOfPages;
@property (nonatomic, retain) UIPageViewController *pageViewController;
@property (nonatomic, retain) NSTextStorage *currentDocument;
@property (nonatomic, retain) NSLayoutManager *layoutManager;
@end
@implementation ReaderViewController
- (instancetype)initWithDocument:(NSTextStorage *)document {
if ((self = [super init])) {
_currentDocument = document;
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
_layoutManager = [[NSLayoutManager alloc] init];
[self.layoutManager setTextStorage:self.currentDocument];
self.layoutManager.delegate = self;
_pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll
navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal
options:nil];
self.pageViewController.view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
self.pageViewController.dataSource = self;
[self addChildViewController:self.pageViewController];
[self.view addSubview:self.pageViewController.view];
// the numberOfPages accessor lazily calculates the number of pages needed to contain the document
for (int i = 0; i < self.numberOfPages; ++i) {
NSTextContainer *container = [[NSTextContainer alloc] init];
container.size = [self _textFrame].size;
[self.layoutManager addTextContainer:container];
}
[self.pageViewController setViewControllers:@[[self viewControllerForPageNumber:0]] direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
}
- (UIViewController *)viewControllerForPageNumber:(NSUInteger)pageNumber {
if (pageNumber >= self.numberOfPages) {
return nil;
}
// SinglePageViewController is a lightweight view controller that has a UITextView and a page number
SinglePageViewController *vc = [[SinglePageViewController alloc] init];
UITextView *textView = [[UITextView alloc] initWithFrame:[self _textFrame] textContainer:[self.layoutManager.textContainers objectAtIndex:pageNumber]];
textView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
textView.scrollEnabled = NO;
textView.editable = NO;
[textView setFont:[UIFont fontWithName:@"IowanOldStyle-Roman" size:20.f]];
[vc.view addSubview:textView];
vc.textView = textView;
vc.pageNumber = pageNumber;
return vc;
}
#pragma mark - UIPageViewControllerDataSource
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController {
NSUInteger currentPage = [(SinglePageViewController *)viewController pageNumber];
if (currentPage >= self.numberOfPages) {
return nil;
}
return [self viewControllerForPageNumber:currentPage + 1];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController {
NSUInteger currentPage = [(SinglePageViewController *)viewController pageNumber];
if (currentPage == 0) {
return nil;
}
return [self viewControllerForPageNumber:currentPage - 1];
}
#pragma mark - Private
- (CGRect)_textFrame {
return CGRectInset(self.view.bounds, 5., 0.);
}
@end