本文转载至 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];
    }
}

最新文章

  1. jquery插件编写模版
  2. IOS随机随学
  3. php本地及远程文件包含漏洞
  4. Python基础知识之排序法
  5. 3d加速的一些问题
  6. C语言 文件操作2--文件缓存的理解
  7. JBOss启动只能在本机访问的解决办法
  8. apache开源项目--Shiro
  9. PHP手册 – 变量和常量
  10. 在线App开发平台——应用之星傻瓜式开发平台
  11. xp和win 2003远程桌面强制进入命令
  12. Spot light工具集
  13. 再说重写IHttpHandler,实现前后端分离
  14. iOS特性
  15. Python爬虫 正则表达式
  16. 给linux虚拟机添加Samba用户
  17. Windows Server 2012 删除IIS之后 重新启动 桌面不出来 只出现一个命令提示框 解决方法
  18. day9集合以及这段时间的总结 未完待续
  19. Alpha 事后诸葛亮(团队)
  20. Apache Curator is a Java/JVM client library for Apache ZooKeeper

热门文章

  1. 【招聘App】—— React/Nodejs/MongoDB全栈项目:socket.io&amp;聊天实现
  2. 转:http2基本中文翻译
  3. scanf函数具体解释与缓冲区
  4. 小米miui系统怎么关闭文件管理里的热门视频和表情?
  5. jmeter 之 BSF,BeanShell(转载)
  6. PL/SQL 异常错误处理
  7. Refactoring之——代码的坏味道(一)过长方法
  8. silverlight计时器
  9. 小程序排错(redis导致)
  10. TFTP 与 FTP的区别