すっとできたと思ったら、意外と苦労した、、でも絵文字対応してません。
いつかね
/**
* 最後に『...続きを読む』をつける
*/
+ (void)seeMoreTruncatingTail:(UITextView *)textView numberOfLines:(int)numberOfLines
{
// 省略文字
NSString *seeMoreString = [NSString stringWithFormat:@" ...%@",NSLocalizedString(@"続きを読む", @"See More")];
// オリジナルサイズ
textView.textContainer.lineBreakMode = NSLineBreakByCharWrapping;
// はかりなおしがうまくいかないときがあるので使わない
// textView.textContainer.maximumNumberOfLines = numberOfLines;
// CGSize originalSize = [textView sizeThatFits:textView.frame.size];
CGSize originalSize = textView.frame.size;
// フルサイズ
textView.textContainer.maximumNumberOfLines = 0;
textView.text = textView.text; // 入れなおさないとうまくいかない時がある
CGSize fullSize = [textView sizeThatFits:CGSizeMake((CGFloat)textView.width,CGFLOAT_MAX)];
// 省略するかどうか
CGFloat restHeight = originalSize.height;
NSString *text = textView.text;
NSString *inputText = @"";
NSString *line = textView.text;
// 心配だったらこっちもいれとく
if (numberOfLines == 3) {
restHeight = 17.5; // ※サンプル数字
} else if (numberOfLines == 2) {
restHeight = 14.5; // ※サンプル数字
}
if (fullSize.height > originalSize.height + SPACE_S) {
// 改行があるとき
NSRange searchResult = [textView.text rangeOfString:@"\n"];
if (searchResult.location != NSNotFound) {
NSRange range, subRange;
// 最初に文字列全範囲を示すRangeを作成する
range = NSMakeRange(0, text.length);
// 1行ずつ読み出す
while (range.length > 0) {
// 1行分を示すRangeを取得
subRange = [text lineRangeForRange:NSMakeRange(range.location,0)];
// 1行分を示すRangeを用いて、文字列から1行抜き出す
line = [text substringWithRange:subRange];
range.location = NSMaxRange(subRange);
range.length -= subRange.length;
textView.text = [line stringByReplacingOccurrencesOfString:@"\n"withString:@""];
CGSize lineSize = [textViewsizeThatFits:CGSizeMake((CGFloat)textView.width, CGFLOAT_MAX)];
// この文で最大行を超えているか
if (restHeight - lineSize.height < SPACE_S) {
break;
}
inputText = [NSString stringWithFormat:@"%@%@", inputText, line];
restHeight = restHeight - lineSize.height;
}
}
// 最後が改行だけでなければ改行をぬく
int plusCount = 0;
BOOL isNoCut = NO;
NSString *originalLine = line;
if ([line isEqualToString:@"\n"] == NO) {
line = [line stringByReplacingOccurrencesOfString:@"\n" withString:@""];
if ([line isEqualToString:originalLine] == NO) {
plusCount++;
// 最後の改行を抜いて省略文字をいれてみよう
textView.text = [NSString stringWithFormat:@"%@%@", line, seeMoreString];
CGSize lineSize = [textViewsizeThatFits:CGSizeMake((CGFloat)textView.width, CGFLOAT_MAX)];
if (restHeight > lineSize.height) {
isNoCut = YES;
}
}
}
// 表示文字数を取得
NSAttributedString *attrString = [[NSAttributedString alloc]initWithString:line
attributes:@{NSFontAttributeName:textView.font}];
CTFramesetterRef framesetter =CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attrString);
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, CGRectMake(0, 0, textView.width, restHeight));
CTFrameRef frame = CTFramesetterCreateFrame(framesetter,CFRangeMake(0, 0), path, NULL);
CFRange actuallyRenderedRange = CTFrameGetVisibleStringRange(frame);
// 省略文字のバイト数分を引く
NSString *actuallyRenderedText = line;
if (isNoCut == NO
&& (int)(actuallyRenderedRange.length > (int)[seeMoreStringlengthOfBytesUsingEncoding:NSShiftJISStringEncoding])) {
// 省略部分がすべて全角なら文字数分引く
NSString *delString = [linesubstringWithRange:NSMakeRange((int)actuallyRenderedRange.length - (int)seeMoreString.length, (int)seeMoreString.length)];
if ((int)delString.length*2 == (int)[delStringlengthOfBytesUsingEncoding:NSShiftJISStringEncoding]) {
actuallyRenderedText = [line substringWithRange:NSMakeRange(0, (int)((int)actuallyRenderedRange.length - (int)seeMoreString.length + plusCount))];
// それ以外はバイト数分
} else {
actuallyRenderedText = [line substringWithRange:NSMakeRange(0, (int)((int)actuallyRenderedRange.length - (int)[seeMoreStringlengthOfBytesUsingEncoding:NSShiftJISStringEncoding] + plusCount))];
}
}
// リリース
CGPathRelease(path);
CFRelease(framesetter);
CFRelease(frame);
// 省略文字をつけてセット
NSMutableAttributedString *attrMutableString = [[NSMutableAttributedString alloc] init];
NSAttributedString *string1 = [[NSAttributedString alloc] initWithString:
[NSString stringWithFormat:@"%@%@", inputText, actuallyRenderedText]
attributes:@{NSFontAttributeName:textView.font,
NSForegroundColorAttributeName:textView.textColor}];
NSAttributedString *string2 = [[NSAttributedString alloc]initWithString:seeMoreString
attributes:@{NSFontAttributeName:[UIColor blackColor],
NSForegroundColorAttributeName:[UIColor grayColor]}];
[attrMutableString appendAttributedString:string1];
[attrMutableString appendAttributedString:string2];
textView.textContainer.maximumNumberOfLines = numberOfLines;
textView.attributedText = attrMutableString;
}
return;
}
参考まで