首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >UIPageViewController/TextKit回放分页文本

UIPageViewController/TextKit回放分页文本
EN

Stack Overflow用户
提问于 2014-07-12 07:44:58
回答 2查看 2K关注 0票数 4

我正在开发一个由TextKit支持的多页阅读应用程序,该应用程序基于2013年WWDC的“高级文本布局和文本工具包的效果”会话(但有些代码是通过不完整的示例重构的)。基本结构是预先计算文本所需的页数,然后为每个页面创建一个NSTextContainer并将其添加到NSLayoutManager中。每当UIPageViewController请求下一页或上一页时,您就创建一个新的UITextView,并通过从NLayoutManger的NSTextContainers数组中选择正确的文本容器来设置它的支持文本容器。

不幸的是,我遇到了一个问题,就是在第一页和第一次回页到任何给定的页面时,文本都会被重新填充。下面是它的样子:

这并不是最显眼的效果(如果你错过了,在回呼时注意屏幕的顶部),但它有点迷茫,如果可能的话,我想消除它。考虑到文本容器应该预先计算,我不明白它为什么要重新填充文本,也不明白如何防止它。有人知道问题出在哪里吗?

编辑:添加代码示例。

代码语言:javascript
复制
@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
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-11-30 08:40:13

我也面临着同样的问题。我的解决方案是将scrollEnabled放在addSubview之后,强制textContainer重新计算大小。见下文代码:

代码语言:javascript
复制
vc.view.addSubview(textView)
textView.scrollEnabled = false;

更新.最后,我想我找到了正确的答案.我们需要在didChangeGeometryFromSize回调中重置容器大小。如果不是真的,请纠正我:)

代码语言:javascript
复制
func layoutManager(layoutManager: NSLayoutManager, 
                   textContainer: NSTextContainer, 
                   didChangeGeometryFromSize oldSize: CGSize) {

    textContainer.size = self.textFrame().size;
    println(textContainer.size.width)
    println(textContainer.size.height)
}
票数 3
EN

Stack Overflow用户

发布于 2015-11-12 11:14:08

尝试将视图控制器的automaticallyAdjustsScrollViewInsets设置为NO

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24710845

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档