同様の問題があり、Mike が投稿した解決策を使用しました。
ただし、trimToWord
指定した UILabel サイズに収まらない単語が多すぎることがよくありました。while ループ演算子を > だけでなく >= に変更すると、完全に機能することがわかりました。
また、残りの文字列を取得するために使用した ivar(chopIndex
およびremainingBody
) をいくつか追加して、次の UILabel に表示できるようにしました。
これが私が使用した解決策です。
-(NSString*) rewindOneWord:(NSString*) str{
// rewind by one word
NSRange lastspace = [str rangeOfString:@" " options:NSBackwardsSearch];
if (lastspace.location != NSNotFound){
int amount = [str length]-lastspace.location;
chopIndex -= amount;
return [str substringToIndex:lastspace.location];
}else {
// no spaces, lets just rewind 2 characters at a time
chopIndex -= 2;
return [str substringToIndex:[str length]-2];
}
}
// returns only how much text it could render with the given stipulations
-(NSString*) trimToWord:(NSString*)str sizeConstraints:(CGSize)availableSize withFont:(UIFont*)font{
if(str == @"")
return str;
CGSize measured = [str sizeWithFont:font constrainedToSize:CGSizeMake(availableSize.width, CGFLOAT_MAX) lineBreakMode:UILineBreakModeWordWrap];
// 'guess' how much we will need to cut to save on processing time
float choppedPercent = (((double)availableSize.height)/((double)measured.height));
if(choppedPercent >= 1.0){
//entire string can fit in availableSize
remainingBody = @"";
return str;
}
chopIndex = choppedPercent*((double)[str length]);
str = [str substringToIndex:chopIndex];
// rewind to the beginning of the word in case we are in the middle of one
do{
str = [self rewindOneWord:str];
measured = [str sizeWithFont:font constrainedToSize:availableSize lineBreakMode:UILineBreakModeWordWrap];
}while(measured.height>=availableSize.height);
//increment past the last space in the chopIndex
chopIndex++;
//update the remaining string
remainingBody = [remainingBody substringFromIndex:chopIndex];
return str;
}