电子书分页显示-----源代码

来源:互联网 发布:剑网三眉间雪捏脸数据 编辑:程序博客网 时间:2024/05/19 17:02

超长字符串分页是所有做电子书之类的程序都会遇到的一个问题. 前一阵搞一个项目, 花了3天时间搞这个小方法, 总是分页不够精确.谢谢CCLV@CocoaChina 在老婆生病的时候还给我提供帮助 :) 最后我发现了问题所在:要用UILabel来显示文字, 而不是TextView!!

我发现盛大起点中文的电子书app还存在分页不准的问题, 李博 要努力噢 哈哈~~

大体思路就是,把字符串分段落, 用段落去填充页. 下面是这个小方法, 希望会对大家有帮助:

-(NSArray*)getPagesOfString:(NSString*)cachewithFont:(UIFont*)font inRect:(CGRect)r{

//返回一个数组,包含每一页的字符串开始点和长度(NSRange)

NSMutableArray*ranges=[NSMutableArray array];

//断行类型

UILineBreakModelineBreakMode=UILineBreakModeCharacterWrap;

//显示字体的行高

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=[cachecomponentsSeparatedByString:@"\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];

}


原创粉丝点击