实现iPhone电子书的分页显示功能(附代码)

移动开发 iOS
制作iPhone电子书时,如果把大段文字放在 UITextView 或 UILabel 里显示,是不能分页的,阅读时就像再看一大卷滚不到头的纸带,用户体验很差。下面这段代码可以实现 UILabel 尺寸固定,根据文本内容和字体动态分页显示,电子书方面的应用应该非常有用。

最近我们介绍了几个iPhone开发的代码测试案例,今天我们将介绍iPhone电子书的分页功能的代码。制作iPhone电子书时,如果把大段文字放在 UITextView 或 UILabel 里显示,是不能分页的,阅读时就像再看一大卷滚不到头的纸带,用户体验很差。下面这段代码可以实现 UILabel 尺寸固定,根据文本内容和字体动态分页显示,电子书方面的应用应该非常有用。 

  1. // Implement viewDidLoad to do additional setup after loading the view, typically from a nib.  
  2. - (void)viewDidLoad {  
  3.     [super viewDidLoad];  
  4.       
  5.     //  
  6.     totalPages = 0;  
  7.     currentPage = 0;  
  8.       
  9.     //  
  10.     textLabel.numberOfLines = 0;  
  11.       
  12.     //  
  13.     if (!text) {  
  14.         // 从文件里加载文本串  
  15.         [self loadString];  
  16.           
  17.         // 计算文本串的大小尺寸  
  18.         CGSize totalTextSize = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE_MAX]  
  19.                                          constrainedToSize:CGSizeMake(textLabel.frame.size.width, CGFLOAT_MAX)  
  20.                                     lineBreakMode:UILineBreakModeWordWrap];  
  21.  
  22.         // 如果一页就能显示完,直接显示所有文本串即可。  
  23.         if (totalTextSize.height < textLabel.frame.size.height) {  
  24.             texttextLabel.text = text;  
  25.         }  
  26.         else {  
  27.             // 计算理想状态下的页面数量和每页所显示的字符数量,只是拿来作为参考值用而已!  
  28.             NSUInteger textLength = [text length];  
  29.             referTotalPages = (int)totalTextSize.height/(int)textLabel.frame.size.height+1;  
  30.             referCharatersPerPage = textLength/referTotalPages;  
  31.               
  32.             // 申请最终保存页面NSRange信息的数组缓冲区  
  33.             int maxPages = referTotalPages;  
  34.             rangeOfPages = (NSRange *)malloc(referTotalPages*sizeof(NSRange));  
  35.             memset(rangeOfPages, 0x0, referTotalPages*sizeof(NSRange));  
  36.               
  37.             // 页面索引  
  38.             int page = 0;  
  39.               
  40.             for (NSUInteger location = 0; location < textLength; ) {  
  41.                 // 先计算临界点(尺寸刚刚超过UILabel尺寸时的文本串)  
  42.                 NSRange range = NSMakeRange(location, referCharatersPerPage);  
  43.                   
  44.                 // reach end of text ?  
  45.                 NSString *pageText;  
  46.                 CGSize pageTextSize;  
  47.                   
  48.                 while (range.location + range.length < textLength) {  
  49.                     pageText = [text substringWithRange:range];  
  50.                       
  51.                     pageTextSize = [pageText sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE_MAX]  
  52.                                         constrainedToSize:CGSizeMake(textLabel.frame.size.width, CGFLOAT_MAX)  
  53.                                             lineBreakMode:UILineBreakModeWordWrap];  
  54.                       
  55.                     if (pageTextSize.height > textLabel.frame.size.height) {  
  56.                         break;  
  57.                     }  
  58.                     else {  
  59.                         range.length += referCharatersPerPage;  
  60.                     }  
  61.                 }  
  62.                   
  63.                 if (range.location + range.length >= textLength) {  
  64.                     range.length = textLength - range.location;  
  65.                 }  
  66.                   
  67.                 // 然后一个个缩短字符串的长度,当缩短后的字符串尺寸小于textLabel的尺寸时即为满足  
  68.                 while (range.length > 0) {  
  69.                     pageText = [text substringWithRange:range];  
  70.                       
  71.                     pageTextSize = [pageText sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE_MAX]  
  72.                                         constrainedToSize:CGSizeMake(textLabel.frame.size.width, CGFLOAT_MAX)  
  73.                                             lineBreakMode:UILineBreakModeWordWrap];  
  74.                       
  75.                     if (pageTextSize.height <= textLabel.frame.size.height) {  
  76.                         range.length = [pageText length];  
  77.                         break;  
  78.                     }  
  79.                     else {  
  80.                         range.length -2;  
  81.                     }  
  82.                 }  
  83.                   
  84.                 // 得到一个页面的显示范围  
  85.                 if (page >= maxPages) {  
  86.                     maxPages += 10;  
  87.                     rangeOfPages = (NSRange *)realloc(rangeOfPages, maxPages*sizeof(NSRange));  
  88.                 }  
  89.                 rangeOfPages[page++] = range;  
  90.                   
  91.                 // 更新游标  
  92.                 location += range.length;  
  93.             }  
  94.  
  95.             // 获取最终页面数量  
  96.             totalPages = page;  
  97.               
  98.             // 更新UILabel内容  
  99.             textLabel.text = [text substringWithRange:rangeOfPages[currentPage]];  
  100.         }  
  101.     }  
  102.       
  103.     // 显示当前页面进度信息,格式为:"8/100"  
  104.     pageInfoLabel.text = [NSString stringWithFormat:@"%d/%d", currentPage+1, totalPages];  
  105. }  
  106.  
  107.  
  108. ////////////////////////////////////////////////////////////////////////////////////////  
  109. // 上一页  
  110. - (IBAction)actionPrevious:(id)sender {  
  111.     if (currentPage > 0) {  
  112.         currentPage--;  
  113.           
  114.         NSRange range = rangeOfPages[currentPage];  
  115.         NSString *pageText = [text substringWithRange:range];  
  116.           
  117.         textLabel.text = pageText;  
  118.  
  119.         //  
  120.         pageInfoLabel.text = [NSString stringWithFormat:@"%d/%d", currentPage+1, totalPages];  
  121.     }  
  122. }  
  123.  
  124. ////////////////////////////////////////////////////////////////////////////////////////  
  125. // 下一页  
  126. - (IBAction)actionNext:(id)sender {  
  127.     if (currentPage < totalPages-1) {  
  128.         currentPage++;  
  129.           
  130.         NSRange range = rangeOfPages[currentPage];  
  131.         NSString *pageText = [text substringWithRange:range];  
  132.           
  133.         textLabel.text = pageText;  
  134.           
  135.         //  
  136.         pageInfoLabel.text = [NSString stringWithFormat:@"%d/%d", currentPage+1, totalPages];  
  137.     }  
  138. }  

在设计iPhone电子书时,一定要注意UILabel 尺寸固定,否则是无法实现iPhone电子书的分页。

[[15730]]

【编辑推荐】

  1. iPhone内存管理面面观 自动释放与便捷方法
  2. iPhone内存管理面面观 对象所有权与引用计数
  3. iPhone开发入门守则:Objective-C编码规范
  4. iPhone开发入门篇 “Hello World”分析代码
责任编辑:佚名 来源: cocoachina
相关推荐

2011-08-19 09:54:40

iPhone开发电子书字符串

2011-08-08 10:42:46

iPhone UITableVie 分页

2009-06-12 16:52:49

2020-03-03 15:17:45

Linux电子书命令

2013-06-14 10:13:06

PythonPython电子书Python教程

2011-06-27 13:17:56

Java

2012-03-20 09:43:11

Boogie Boar

2010-07-19 16:57:45

盈动电子书包12大功能全接触

2011-12-13 14:43:29

51CTO

2020-06-15 18:20:37

Fedora电子书开源

2012-04-13 18:57:22

2018-12-26 10:06:28

Linux电子书阅读器命令

2017-01-19 19:03:25

微软Edge浏览器电子书

2009-06-17 16:12:26

java电子书制作软件

2018-12-05 16:00:32

MongoDB数据库NoSQL

2016-11-23 08:48:24

LinuxCalibre电子书

2013-07-11 09:57:43

苹果电子书

2019-12-16 11:12:48

开源技术 数据

2011-03-28 15:57:03

Python

2023-11-19 18:58:12

LinuxFoliate
点赞
收藏

51CTO技术栈公众号