[转载]解决超长字符串分页问题,公布代码
来源:互联网 发布:电影院票房数据 编辑:程序博客网 时间:2024/05/27 06:14
这是所有做电子书之类的程序都会遇到的一个问题. 前一阵搞一个项目, 花了3天时间搞这个小方法, 总是分页不够精确.谢谢CCLV@CocoaChina 在老婆生病的时候还给我提供帮助 :) 最后我发现了问题所在:要用UILabel来显示文字, 而不是TextView!!
我发现盛大起点中文的电子书app还存在分页不准的问题, 李博 要努力噢 哈哈~~
大体思路就是,把字符串分段落, 用段落去填充页. 下面是这个小方法, 希望会对大家有帮助:
-(NSArray*)getPagesOfString:(NSString*)cache withFont:(UIFont*)fontinRect:(CGRect)r{
//返回一个数组,包含每一页的字符串开始点和长度(NSRange)
NSMutableArray*ranges=[NSMutableArray array];
//断行类型
UILineBreakModelineBreakMode=UILineBreakModeCharacter
Wrap; //显示字体的行高
CGFloat lineHeight=[@"Sample样本"sizeWithFont:font].height;
NSIntegermaxLine=floor(r.size.height/lineHeight);
NSInteger totalLines=0;
NSLog(@”Max Line Per Page: %d(%.2f/%.2f)”,maxLine,r.size.height,lineHeight);
NSString *lastParaLeft=nil;
NSRange range=NSMakeRange(0, 0);
//把字符串按段落分开, 提高解析效率
NSArray *paragraphs=[cachecomponentsSeparatedByStr
ing:@"n"]; for (int p=0;p< [paragraphscount];p++) {
NSString *para;
if (lastParaLeft!=nil) {
//上一页完成后剩下的内容继续计算
para=lastParaLeft;
lastParaLeft=nil;
}else {
para=[paragraphs objectAtIndex:p];
if (p<[paragraphscount]-1)
para=[para stringByAppendingString:@"n"];//刚才分段去掉了一个换行,现在换给它
}
CGSize paraSize=[parasizeWithFont:font
constrainedToSize:r.size
lineBreakMode:lineBreakMode];
NSIntegerparaLines=floor(paraSize.height/lineHeight);
if (totalLines+paraLines<maxLine){
totalLines+=paraLines;
range.length+=[para length];
if (p==[paragraphs count]-1) {
//到了文章的结尾 这一页也算
[ranges addObject:[NSValuevalueWithRange:range]];
//IMILog(@”===========PageOver=============”);
}
}else if (totalLines+paraLines==maxLine){
//很幸运, 刚好一段结束,本页也结束, 有这个判断会提高一定的效率
range.length+=[para length];
[ranges addObject:[NSValuevalueWithRange:range]];
range.location+=range.length;
range.length=0;
totalLines=0;
//IMILog(@”===========PageOver=============”);
}else{
//重头戏, 页结束时候本段文字还有剩余
NSInteger lineLeft=maxLine-totalLines;
CGSize tmpSize;
NSInteger i;
for (i=1; i<[para length]; i++){
//逐字判断是否达到了本页最大容量
NSString *tmp=[parasubstringToIndex:i];
tmpSize=[tmp sizeWithFont:font
constrainedToSize:r.size
lineBreakMode:lineBreakMode];
intnowLine=floor(tmpSize.height/lineHeight);
if (lineLeft<nowLine) {
//超出容量,跳出, 字符要回退一个, 应为当前字符已经超出范围了
lastParaLeft=[parasubstringFromIndex:i-1];
break;
}
}
range.length+=i-1;
[ranges addObject:[NSValuevalueWithRange:range]];
range.location+=range.length;
range.length=0;
totalLines=0;
p–;
//IMILog(@”===========PageOver=============”);
}
}
return [NSArrayarrayWithArray:ranges];
}
如果您有更好的方法, 希望不吝赐教 :)
原文:http://b.imi.im/?p=388
- [转载]解决超长字符串分页问题,公布代码
- 解决超长字符串分页问题
- 超长字符串分页
- 使用javascript解决字符串超长显示的问题
- 解决AndroidStudio的logcat显示超长字符串的问题
- 字符串连接超长的解决wmsys.wm_concat()
- 字符串连接超长的解决(一)
- 字符串连接超长的解决(二)
- 解决HTML表格连续超长英文字符串不能正确换行问题
- SQLServer 存储过程处理超长字符串问题
- 超长字符串
- 超长字符串
- 电子书中超长字符串(章节内容)分页的算法
- 超长文本分页
- HTML表格中超长字符串强制换行代码
- HTML表格中超长字符串强制换行问题
- 用JSPGen实现JSP字符串分页显示方法(支持超长字符串)
- 活用CSS巧妙解决超长文本内容显示问题
- Oracle 常用SQL技巧收藏
- DataGridView 列宽设置
- 尧尧拔牙记(二)
- oracle lob 数据类型
- 用jquery控制图片的最大宽度
- [转载]解决超长字符串分页问题,公布代码
- 尧尧拔牙记(三)
- Ogre1.7.2 + CEGUI0.7.5配置
- 代码中的命名规范及原则
- ASP.Net中控件的EnableViewState属性
- java学习路线
- Xdebug与PHPUnit
- 关于 ie getAttribute() 的实现bug
- iphone app中读取本地txt,csv文件 转载