-(NSArray*)getPagesOfString:(NSString*)cache withFont:(UIFont*)font inRect:(CGRect)r{ //返回一个数组, 包含每一页的字符串开始点和长度(NSRange) NSMutableArray *ranges=[NSMutableArray array]; //显示字体的行高 CGFloat lineHeight=[@"Sample样本" sizeWithFont:font].height; NSInteger maxLine=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=[cache componentsSeparatedByString:@"/n"]; for (int p=0;p< [paragraphs count];p++) { NSString *para; if (lastParaLeft!=nil) { //上一页完成后剩下的内容继续计算 para=lastParaLeft; lastParaLeft=nil; }else { para=[paragraphs objectAtIndex:p]; if (p<[paragraphs count]-1) para=[para stringByAppendingString:@"/n"]; //刚才分段去掉了一个换行,现在还给它 } CGSize paraSize=[para sizeWithFont:font constrainedToSize:r.size lineBreakMode:lineBreakMode]; NSInteger paraLines=floor(paraSize.height/lineHeight); if (totalLines+paraLines<maxLine) { totalLines+=paraLines; range.length+=[para length]; if (p==[paragraphs count]-1) { //到了文章的结尾 这一页也算 [ranges addObject:[NSValue valueWithRange:range]]; //IMILog(@”===========Page Over=============”); } }else if (totalLines+paraLines==maxLine) { //很幸运, 刚好一段结束,本页也结束, 有这个判断会提高一定的效率 range.length+=[para length]; [ranges addObject:[NSValue valueWithRange:range]]; range.location+=range.length; range.length=0; totalLines=0; //IMILog(@”===========Page Over=============”); }else{ //重头戏, 页结束时候本段文字还有剩余 NSInteger lineLeft=maxLine-totalLines; CGSize tmpSize; NSInteger i; for (i=1; i<[para length]; i++) { //逐字判断是否达到了本页最大容量 NSString *tmp=[para substringToIndex:i]; tmpSize=[tmp sizeWithFont:font constrainedToSize:r.size lineBreakMode:lineBreakMode]; int nowLine=floor(tmpSize.height/lineHeight); if (lineLeft<nowLine) { //超出容量,跳出, 字符要回退一个, 应为当前字符已经超出范围了 lastParaLeft=[para substringFromIndex:i-1]; break; } } range.length+=i-1; [ranges addObject:[NSValue valueWithRange:range]]; range.location+=range.length; range.length=0; totalLines=0; p--; //IMILog(@”===========Page Over=============”); } } return [NSArray arrayWithArray:ranges]; }