11

看着 iBooks 应用程序,我想知道它是如何完成文本格式的(可能是一个非常简单的 txt 文件),以便它不能滚动,而是分成不同的页面。

我想达到同样的效果,但只能使用可编辑的文本。

我需要从哪里开始?UITextView 在滚动时不起作用。即使我将 pagingEnabled 属性设置为 YES,它也不会完成这项工作。

似乎我需要限制我可以放在某个页面上的文本数量。是否有限制 UITextView 输入的功能?我需要限制 LINES 的数量(不是字符),因为它们会显示在整个 iPhone 屏幕上(我猜你可以容纳 20 行左右,具体取决于字体大小)。

任何帮助,将不胜感激!由于我是初学者,我特别欣赏使用类似方法的示例。

谢谢!

4

2 回答 2

2

您需要的是一个自己的布局算法,它可以获取文本、测量其大小并对其进行剪切,直到它适合单页文本视图。然后从其余的文本开始,下一个文本视图也一样,依此类推......之后(或在算法内部)您将所有结果文本视图排列在滚动视图(或数组中,稍后您会翻阅带有分页动画 - 如果你喜欢它俗气)。我做了类似的事情,但是使用 UILabels,它也应该与 textviews 一起使用。你需要的是:NSString's - (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size和 r angeOfString:@" " options:NSBackwardsSearch(寻找单词空间)和substringFromIndex: resp。substringToIndex:

如果您需要更多信息,请发表评论。

编辑

嗨,以下代码未经测试,但包含您需要的大部分内容(希望如此),但可能存在一些错误,尤其是在递归方面......我更正了 BackWardsSearch 的想法,因为它可能需要很长时间才能缩短文本。我完全忽略了——这可能真的很棘手——在编辑时重新渲染。但无论如何,这是代码。这是一个假定给旧 4 个成员的视图控制器(未发布头文件):

  UIView *editableBook;
  NSMutableArray *content;
  int currentPage;
  UIFont *font;

这是控制器本身:

//
//  EditableBookController.m
//
//  Created by Kai on 09.03.11.
//

#import "EditableBookController.h"


@implementation EditableBookController

-(id)initWithText:(NSString *)text
{
  if (self=[super init]) 
  {
    font = [UIFont fontWithName:@"SomeFont" size:12];
    content = [[NSMutableArray alloc]init];
    [self cutInPages:text];
    currentPage = 0;  
  }
  return self;
}

- (void)loadView 
{
  self.view = [[UIView alloc] initWithFrame:CGRectMake(.0, .0, 768., 1024.)];//assuming portrait only ...
  editableBook = [[UIView alloc]initWithFrame:self.view.bounds];//could be a scroll view in alternate approach
  UISwipeGestureRecognizer *flipper = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(nextOrPrevious:)];
  [editableBook addGestureRecognizer:flipper];
  [flipper release];
  [self.view addSubview:editableBook];
  UITextView *textView = [[UITextView alloc]initWithText:[content objectAtIndex:currentPage]];
  textView.frame = editableBook.bounds;
  textView.font = font;
  textView.tag = 23;
  [editableBook addSubview:textView];
  [textView release];
}

-(void)nextOrPrevious:(id)sender
{
  UISwipeGestureRecognizer *flipper = (UISwipeGestureRecognizer*)sender;
  if(flipper.direction == UISwipeGestureRecognizerDirectionLeft)
  {
    [self next];
  }
  else if(flipper.direction == UISwipeGestureRecognizerDirectionRight)
  {
    [self previous];
  }
}

-(void)next
{
  if(currentPage == content.count - 1)
  {
    return;
  }
  currentPage++;
  UIView *fromView = [editableBook viewWithTag:23];
  UIView *toView =  [[UITextView alloc]initWithText:[content objectAtIndex:currentPage]];
  toView.frame = editableBook.bounds;
  toView.tag = 23;
  [UIView transitionWithView:editableBook duration:0.2 options:UIViewAnimationTransitionFlipFromRight
   animations:^
   {
     [fromView removeFromSuperview];
     [editableBook addSubview:toView];
   }
   completion:NULL];
}

-(void)previous
{
  if(currentPage == 0)
  {
    return;
  }
  currentPage--;
  UIView *fromView = [editableBook viewWithTag:23];
  UIView *toView =  [[UITextView alloc]initWithText:[content objectAtIndex:currentPage]];
  toView.frame = editableBook.bounds;
  toView.tag = 23;
  [UIView transitionWithView:editableBook duration:0.2 options:UIViewAnimationTransitionFlipFromLeft
   animations:^
   {
     [fromView removeFromSuperview];
     [editableBook addSubview:toView];
   }
   completion:NULL];
}

-(void)cutInPages:(NSString *)text
{
  NSRange whereToCut = whereToCut = [text rangeOfString:@" "];
  NSString *pageText = [text substringToIndex:whereToCut.location];
  NSString *rest = [text substringFromIndex:whereToCut.location];;
  CGFloat height = 0;
  while (height<1024.) 
  {
    NSRange whereToCut = [rest rangeOfString:@" "];
    NSString *wordOfRest = [rest substringToIndex:whereToCut.location];
    pageText = [NSString stringWithFormat:@"%@%@", pageText, wordOfRest];
    rest = [rest substringFromIndex:whereToCut.location];;
    CGSize size = [pageText sizeWithFont:font
                      constrainedToSize:CGSizeMake(768., 10000) 
                          lineBreakMode:UILineBreakModeWordWrap];
    height = size.height;
  }
  if(height>1024.)
  {
    //TODO cut the last word of pageText and prepend to the eest
  }
  [content addObject:pageText];
  if([rest length] > 0)
  {
    [self cutInPages:rest];
  }
}

- (void)dealloc 
{
  [editableBook release];
  [content release];
  [super dealloc];
}


@end
于 2011-03-08T17:58:10.827 回答
0

我还没有看到源代码,但我愿意保证他们使用CoreText 框架来进行分页和渲染。但是请注意,当它说“低级别”时,它意味着。这是一个直接处理渲染字符的框架。CoreText 很难进行字符选择和插入(您可能希望用于可编辑文本)之类的事情。

我建议使用UIKit 框架中的NSString绘图和大小调整方法。但即便如此,您仍需要做大量工作才能获得此功能。我不认为 UIKit 提供滚动的文本编辑控件。我们假设如果你想编辑文本,它的长度是任意的,这意味着我们把它放在一个可滚动的容器中(这样它就可以是任意长度)。

简而言之,如果您是初学者,我建议您从事其他工作。你所要求的并不是一件容易的事。:)

于 2011-03-08T20:35:48.190 回答