本文转载至 http://blog.csdn.net/zaitianaoxiang/article/details/6650497

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

// Implement viewDidLoad to do additional setup after loadingthe view, typically from a nib.
- (void)viewDidLoad {
    [superviewDidLoad];
    
    //
    totalPages= 0;
    currentPage= 0;
    
    //
    textLabel.numberOfLines= 0;
    
    //
    if(!text) {
        //从文件里加载文本串
        [selfloadString];
        
        //计算文本串的大小尺寸
        CGSizetotalTextSize = [text sizeWithFont:[UIFontsystemFontOfSize:FONT_SIZE_MAX]
                                        constrainedToSize:CGSizeMake(textLabel.frame.size.width,CGFLOAT_MAX)
                                    lineBreakMode:UILineBreakModeWordWrap];

//如果一页就能显示完,直接显示所有文本串即可。
        if(totalTextSize.height < textLabel.frame.size.height){
            textLabel.text= text;
        }
        else{
            //计算理想状态下的页面数量和每页所显示的字符数量,只是拿来作为参考值用而已!
            NSUIntegertextLength = [text length];
            referTotalPages=(int)totalTextSize.height/(int)textLabel.frame.size.height+1;
            referCharatersPerPage= textLength/referTotalPages;
            
            //申请最终保存页面NSRange信息的数组缓冲区
            intmaxPages = referTotalPages;
            rangeOfPages= (NSRange *)malloc(referTotalPages*sizeof(NSRange));
            memset(rangeOfPages,0x0, referTotalPages*sizeof(NSRange));
            
            //页面索引
            intpage = 0;
            
            for(NSUInteger location = 0; location < textLength; ){
                //先计算临界点(尺寸刚刚超过UILabel尺寸时的文本串)
                NSRangerange = NSMakeRange(location, referCharatersPerPage);
                
                //reach end of text ?
                NSString*pageText;
                CGSizepageTextSize;
                
                while(range.location + range.length < textLength) {
                    pageText= [text substringWithRange:range];
                    
                    pageTextSize= [pageText sizeWithFont:[UIFontsystemFontOfSize:FONT_SIZE_MAX]
                                        constrainedToSize:CGSizeMake(textLabel.frame.size.width,CGFLOAT_MAX)
                                            lineBreakMode:UILineBreakModeWordWrap];
                    
                    if(pageTextSize.height > textLabel.frame.size.height){
                        break;
                    }
                    else{
                        range.length+= referCharatersPerPage;
                    }
                }
                
                if(range.location + range.length >= textLength){
                    range.length= textLength - range.location;
                }
                
                //然后一个个缩短字符串的长度,当缩短后的字符串尺寸小于textLabel的尺寸时即为满足
                while(range.length > 0) {
                    pageText= [text substringWithRange:range];
                    
                    pageTextSize= [pageText sizeWithFont:[UIFontsystemFontOfSize:FONT_SIZE_MAX]
                                        constrainedToSize:CGSizeMake(textLabel.frame.size.width,CGFLOAT_MAX)
                                            lineBreakMode:UILineBreakModeWordWrap];
                    
                    if(pageTextSize.height <= textLabel.frame.size.height){
                        range.length= [pageText length];
                        break;
                    }
                    else{
                        range.length-= 2;
                    }
                }
                
                //得到一个页面的显示范围
                if(page >= maxPages) {
                    maxPages+= 10;
                    rangeOfPages= (NSRange *)realloc(rangeOfPages, maxPages*sizeof(NSRange));
                }
                rangeOfPages[page++]= range;
                
                //更新游标
                location+= range.length;
            }

//获取最终页面数量
            totalPages= page;
            
            //更新UILabel内容
            textLabel.text= [text substringWithRange:rangeOfPages[currentPage]];
        }
    }
    
    //显示当前页面进度信息,格式为:"8/100"
    pageInfoLabel.text= [NSString stringWithFormat:@"%d/%d", currentPage+1,totalPages];
}

////////////////////////////////////////////////////////////////////////////////////////
// 上一页
- (IBAction)actionPrevious:(id)sender {
    if(currentPage > 0) {
        currentPage--;
        
        NSRangerange = rangeOfPages[currentPage];
        NSString*pageText = [text substringWithRange:range];
        
        textLabel.text= pageText;

//
        pageInfoLabel.text= [NSString stringWithFormat:@"%d/%d", currentPage+1,totalPages];
    }
}

////////////////////////////////////////////////////////////////////////////////////////
// 下一页
- (IBAction)actionNext:(id)sender {
    if(currentPage < totalPages-1) {
        currentPage++;
        
        NSRangerange = rangeOfPages[currentPage];
        NSString*pageText = [text substringWithRange:range];
        
        textLabel.text= pageText;
        
        //
        pageInfoLabel.text= [NSString stringWithFormat:@"%d/%d", currentPage+1,totalPages];
    }
}

实现 iPhone 电子书的分页显示功能的代码的更多相关文章

  1. iPhone OS 开发 - 了解并解决代码签名问题

    译者:Jestery 发表时间:2010-04-24浏览量:21082评论数:0挑错数:0 了解并解决代码签名问题 (为保持跟开发环境以及APPLE开发者社区网站结构对应,一些名词未作翻译) 绝大多数 ...

  2. Mvc分页组件MvcSimplePager代码重构

    1 Mvc分页组件MvcSimplePager代码重构 1.1 Intro 1.2 MvcSimplePager 代码优化 1.3 MvcSimplePager 使用 1.4 End Mvc分页组件M ...

  3. Mvc分页组件MvcSimplePager代码重构及使用

    1 Mvc分页组件MvcSimplePager代码重构 1.1 Intro 1.2 MvcSimplePager 代码优化 1.3 MvcSimplePager 使用 1.4 End Mvc分页组件M ...

  4. 分页查询关键代码 多条件查询关键代码 删除选中商品关键代码 修改要先回显再修改 修改要先回显再修改 同一业务集中使用同一servlet的方法

    分页查询关键代码: 通过servlet转发回来的各种信息进行分页的设计(转发回的信息有 分页查询的List集合 查询的页码 查询的条数 查询的数据库总条数 查询的总页码) 从开始时循环10次出现十个数 ...

  5. iPhone手机越狱-逆向砸壳-代码注入

    iPhone手机越狱 逆向砸壳 代码注入 工具下载 操作越狱 安装待逆向应用(app) 使用OpenSSH连接手机 找到应用二进制文件地址 找到应用document沙盒地址 拷贝砸壳工具(dumpde ...

  6. django之分页,纯python代码

    Django中分页 py文件代码 """ 自定义分页组件 可以返回分页的数据和分页的HTML代码 """ from django.http ...

  7. 静态页分页功能js代码

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. 转:PHP分页技术的代码和示例

    本文来自:10 Helpful PHP Pagination Scripts For Web Developers 分页是目前在显示大量结果时所采用的最好的方式.有了下面这些代码的帮助,开发人员可以在 ...

  9. php分页实例附代码

    一个典型的PHP分页实例代码分享,学习php的朋友肯定用得到,主要是了解思路: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transit ...

随机推荐

  1. java.io.IOException: Attempted read from closed stream. 异常,解决

    在HttpClient请求的时候,返回结果解析时出现java.io.IOException: Attempted read from closed stream. 异常,解决 原因是EntityUti ...

  2. C指针解析 ------ 运算符&amp;和*

    本文是自己学习所做笔记,欢迎转载,但请注明出处:http://blog.csdn.net/jesson20121020 & 是取地址运算符.* 叫做指针运算符或间接运算符.&a 的运算 ...

  3. C语言-Makefile经典教程(掌握这些足够)

     makefile很重要 什么是makefile? 或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得要作一个好的和professional 的 ...

  4. WORD文档书签管理

    最近在浏览一个word超长文档,在文档中有几处要点用颜色做了标记,但是在下次查找的时候无法定位,还得一页页去翻,而且无法通过目录概览的形式查看总共做了多少处标记 于是想到了书签 原本以为在视图中能够设 ...

  5. elasticsearch 使用快照方式迁移数据

    注册快照仓库 ES是通过快照的方式来实现数据备份,并且是以增量的方式,所以一般第一次做的话会花费较长的时间.为了做快照,那么就需要注册一个快照仓库,告诉ES我们的快照应该如何保存以及将快照保存到哪里. ...

  6. Mysql查询缓存碎片、缓存命中率及Nagios监控

    Mysql 的优化方案,在互联网上可以查找到非常多资料,今天对Mysql缓存碎片和命中率作了详细了解,个人作了简单整理. 一.Mysql查询缓存碎片和缓存命中率. mysql> SHOW STA ...

  7. Atitit  hre框架v5 新特性  HREv5

    Atitit  hre框架v5 新特性  HREv5 1. V5新特性 apiurl2="/wrmiServlet";1 2. V1 新特性1 3. V2 新特性 添加php版1 ...

  8. iOS-NSMutableParagraphStyle段落风格

    apple API: NS_CLASS_AVAILABLE(10_0, 6_0) @interface NSMutableParagraphStyle : NSParagraphStyle @prop ...

  9. dubbo_分布式Rpc服务

    dubbo是一个分布式的服务架构,可直接用于生产环境作为SOA服务或Rpc服务 1.下载,编译,运行demo  1).安装zookeeper    下载:http://apache.claz.org/ ...

  10. Linux操作系统下/etc/hosts文件配置方法

    1.关于/etc/host,主机名和IP配置文件 Hosts - The static table lookup for host name(主机名查询静态表) hosts文件是Linux系统中一个负 ...