問題: 字段由后端控制,里面出現換行的時候
\r\n是成對出現的 , 轉義字符並未納入字符串的計算范圍 。。。 所以導致顯示不全的bug
解決方案一:
由於這個方法計算字符串的大小的通過取得字符串的size來計算, 如果你計算的字符串中包含\r\n 這樣的字符,也只會把它當成字符來計算。但是在顯示的時候就是\n是轉義字符,那么顯示的計算的高度就不一樣了,所以可以采用:計算的高度 = boundingRectWithSize計算出來的高度 + \r\n轉義字符出現的個數 * 單行文本的高度。
///MARK:- 查詢字串出現的次數 方法二
- (NSInteger)searchSubStringCountWithSubString:(NSString *)subStr
{
NSUInteger count = 0, length = [subStr length];
NSRange range = NSMakeRange(0, length);
while(range.location != NSNotFound){
range = [self rangeOfString: subStr options:0 range:range];
if(range.location != NSNotFound){
range = NSMakeRange(range.location + range.length, length - (range.location + range.length));
count++;
}
}
return count;
}
解決方案二:
采用UILabel來展示文本就沒有這個坑,主要看自己選擇,畢竟有些特性只有UITextView才有的
@implementation NSString (Extension)
///MARK:- 查詢字串出現的次數 方法一
- (NSInteger)countOccurencesOfString:(NSString*)searchString {
NSInteger strCount = [self length] - [[self stringByReplacingOccurrencesOfString:searchString withString:@""] length];
return strCount / [searchString length];
}
///MARK:- 查詢字串出現的次數 方法二
- (NSInteger)searchSubStringCountWithSubString:(NSString *)subStr
{
NSUInteger count = 0, length = [subStr length];
NSRange range = NSMakeRange(0, length);
while(range.location != NSNotFound){
range = [self rangeOfString: subStr options:0 range:range];
if(range.location != NSNotFound){
range = NSMakeRange(range.location + range.length, length - (range.location + range.length));
count++;
}
}
return count;
}
//計算單行文本寬度和高度,返回值與`UIFont.lineHeight`一致 [手動滑稽]方塊字
- (CGSize)singleLineSizeWithText:(UIFont *)font{
return [self sizeWithAttributes:@{NSFontAttributeName:font}];
}
@end
項目中展示控件使用的是UITextView 文本中包含\r\n來換行 同一個PHP后端這種既定的規則應該不會經常變。
所以:
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
[paragraphStyle setLineBreakMode:NSLineBreakByCharWrapping];
paragraphStyle.lineSpacing = 5;// 字體的行間距
paragraphStyle.alignment = NSTextAlignmentLeft;
NSDictionary *attributes = @{
NSForegroundColorAttributeName : [UIColor whiteColor],
NSParagraphStyleAttributeName : paragraphStyle,
NSFontAttributeName : KFontSize(13)
};
//出現`\r` `\n` 關於計算高度不准確的問題 https://www.jianshu.com/p/c615a76dace2
CGFloat textX = 35;
CGFloat textW = KWIDTH - textX*2;
NSString *realText = shareModel.tips ;
NSInteger warpRowCount = [realText searchSubStringCountOccurencesOfString:@"\r\n"];
CGFloat singleLineHeight = [@"哈哈哈哈哈哈哈哈哈" singleLineSizeWithText:KFontSize(13)].height + 5;
CGFloat addHeight = warpRowCount *singleLineHeight;
CGFloat textH = [realText boundingRectWithSize:CGSizeMake(textW, MAXFLOAT) options:
NSStringDrawingUsesLineFragmentOrigin |
NSStringDrawingUsesFontLeading
attributes: attributes context:nil].size.height + 0.5 + addHeight;
self.textView.frame = CGRectMake(textX, 0, textW , textH);
NSMutableAttributedString * attributeStr = [[NSMutableAttributedString alloc] initWithString: realText attributes:attributes];
self.textView.attributedText = attributeStr;
經過這么一番折騰之后,文本正常顯示了 🤬
終極解決方案
2020年6月24日 其實根本不用這么麻煩,系統自適應方法即可計算准確,評論區已給出答案
參考博客:
boundingRectWithSize計算文字高度不准問題
使用boundingRectWithSize計算內容高度的坑
