博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
实现 iPhone 电子书的分页显示功能
阅读量:6168 次
发布时间:2019-06-21

本文共 5549 字,大约阅读时间需要 18 分钟。

制作 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 textLabel.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 }

 

1 // 上一页  2 - (IBAction)actionPrevious:(id)sender {
3 if (currentPage > 0) {
4 currentPage--; 5 6 NSRange range = rangeOfPages[currentPage]; 7 NSString *pageText = [text substringWithRange:range]; 8 9 textLabel.text = pageText; 10 11 // 12 pageInfoLabel.text = [NSString stringWithFormat:@"%d/%d", currentPage+1, totalPages]; 13 } 14 }

1 // 下一页  2 - (IBAction)actionNext:(id)sender {
3 if (currentPage < totalPages-1) {
4 currentPage++; 5 6 NSRange range = rangeOfPages[currentPage]; 7 NSString *pageText = [text substringWithRange:range]; 8 9 textLabel.text = pageText; 10 11 // 12 pageInfoLabel.text = [NSString stringWithFormat:@"%d/%d", currentPage+1, totalPages]; 13 } 14 }

转载地址:http://xojba.baihongyu.com/

你可能感兴趣的文章
沪江学习安卓端重构实践
查看>>
Scala类型系统的目的——Martin Odersky访谈(三)
查看>>
距离QCon纽约还有3个礼拜:新的演讲、播客节目和研讨会
查看>>
.NET或将引入类型类和扩展
查看>>
.NET特性:异步流
查看>>
当编程语言掌握在企业手中,是生机还是危机?
查看>>
Python 2寿命即将终结,在此之前你需要做些什么?
查看>>
Swift 烧脑体操(五)- Monad
查看>>
用Lean Pilots推动改进
查看>>
回顾:在生产环境中使用Haskell
查看>>
高效运维最佳实践(02):员工的四大误区及解决之道
查看>>
又拍云推三款场景化CDN应用 目标行业第二
查看>>
北大AI公开课2019 | 商汤科技沈徽:AI创新与落地
查看>>
avalon2.2.3发布
查看>>
Mango 的组织重构
查看>>
从起步到爆发,UPYUN云CDN架构演进之路
查看>>
Elixir 1.2带来多项功能增强和性能提升
查看>>
[elixir! #0021][译] 使用Phoenix和Websockets创建一个游戏大厅系统 by Alex Jensen
查看>>
本地vs云:大数据厮杀的最终幸存者会是谁?
查看>>
关于Visual Studio 2019的前期详情
查看>>