需求:设置标题,最多显示两行,多余的字符串以"..."截断,并在标题末尾追加编辑按钮
-
获取UITextView中任一字符位置
- (CGRect)rectOfCharacterAtIndex:(NSInteger)index inTextView:(UITextView *)textView { if (!textView) { return CGRectZero; } NSString *text = textView.text; if (index <= 0 && index >= text.length) { return CGRectZero; } // 获取每个字符的位置 [textView setSelectedRange:NSMakeRange(index,1)]; NSArray<UITextSelectionRect *> *rects = [textView selectionRectsForRange:textView.selectedTextRange]; [textView setSelectedRange:NSMakeRange(0, 0)]; // 获取字符有效的位置 CGRect charRect = rects.firstObject.rect; for (UITextSelectionRect *rect in rects) { // rect有效的情况下 if (rect.rect.size.width > 0 && rect.rect.size.height > 0) { if (CGRectGetMinY(charRect) < CGRectGetMinY(rect.rect)) { charRect = rect.rect; } else if (CGRectGetMinY(charRect) == CGRectGetMinY(rect.rect) && CGRectGetMinX(charRect) < CGRectGetMinX(rect.rect)) { charRect = rect.rect; } } } return charRect; }
-
获取每一行字符串的长度及该行最后一个字符下标
// 计算每一行的rect及最后一个字符的下标 - (NSArray *)lineInformaitonOfTextView:(UITextView *)textView { NSString *text = textView.text; NSMutableDictionary<NSString *, NSDictionary *> *lineInfo = [NSMutableDictionary dictionary]; for (NSInteger index = 0; index < text.length; index++) { CGRect charRect = [self rectOfCharacterAtIndex:index inTextView:textView]; NSString *YKey = [NSString stringWithFormat:@"%.0f", charRect.origin.y]; NSMutableDictionary *info = [lineInfo[YKey] mutableCopy]; if (!info) { info = [NSMutableDictionary dictionary]; } info[@"lastCharIndex"] = @(index); if (!info[@"rect"]) { info[@"rect"] = [NSValue valueWithCGRect:charRect]; } else { CGRect rect = [info[@"rect"] CGRectValue]; if (rect.origin.x > charRect.origin.x) { rect.origin.x = charRect.origin.x; } if (rect.origin.y > charRect.origin.y) { rect.origin.y = charRect.origin.y; } if (CGRectGetMaxX(rect) < CGRectGetMaxX(charRect)) { rect.size.width = CGRectGetMaxX(charRect) - CGRectGetMinX(rect); } if (CGRectGetMaxY(rect) < CGRectGetMaxY(charRect)) { rect.size.height = CGRectGetMaxY(charRect) - CGRectGetMinY(rect); } info[@"rect"] = [NSValue valueWithCGRect:rect]; } lineInfo[YKey] = info; } // 对行排序 NSMutableArray *allYValue = [lineInfo.allKeys mutableCopy]; [allYValue sortUsingComparator:^NSComparisonResult(NSString *obj1, NSString *obj2) { if (obj1.integerValue <= obj2.integerValue) { return NSOrderedAscending; } else { return NSOrderedDescending; } }]; // 按行顺序返回数据 NSMutableArray *lineArray = [NSMutableArray array]; for (NSString *lineKey in allYValue) { [lineArray addObject:lineInfo[lineKey]]; } return lineArray; }
-
限制行数、及限制最后一行的长度
/** 限制行数且以...在末尾截断,最后一行末尾空出间隔追加控件 * @param numberOfLine 限制行数 * @param appendLength 最后一行的末尾空白区 */ - (void)setString:(NSString *)string attributes:(NSDictionary *)attributes textView:(UITextView *)textView maxNumberOfLine:(NSInteger)numberOfLine appendLength:(CGFloat)appendLength { if (!textView) { return ; } // 设置字符串 string = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; textView.text = string; if (attributes && string) { textView.text = nil; NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:string attributes:attributes]; textView.attributedText = attributeString; } CGRect textFrame = textView.frame; textFrame.size.height = [textView sizeThatFits:CGSizeMake(textFrame.size.width, MAXFLOAT)].height; textView.frame = textFrame; // 获取每一行字符串位置 NSArray *lineInfoArray = [self lineInformaitonOfTextView:textView]; // 当行号等于或超过限制行数时,需调整最后一行的字符,以便能空出appendLength的位置 if (lineInfoArray.count >= numberOfLine) { NSDictionary *lineInfo = lineInfoArray[numberOfLine - 1]; CGFloat adjustLastLineLength = CGRectGetMaxX([lineInfo[@"rect"] CGRectValue]); // 调整过后,最后一行字符的宽度 NSInteger adjustIndex = [lineInfo[@"lastCharIndex"] integerValue]; // 调整过后,字符开始截断的位置 // 最后一行的空余位置不够appendLength时,才需要偏移 if (adjustIndex > 0 && adjustLastLineLength + appendLength > textFrame.size.width) { // 偏移下标,空出appendLength的位置 for (; adjustIndex > 0; adjustIndex--) { CGRect charRect = [self rectOfCharacterAtIndex:adjustIndex inTextView:textView]; if (CGRectGetMinX(charRect) + appendLength < textFrame.size.width) { break; } } // 截断字符串 NSString *adjustText = textView.text; if (adjustIndex >= 0 && adjustIndex < adjustText.length) { adjustText = [adjustText stringByReplacingCharactersInRange:NSMakeRange(adjustIndex, adjustText.length - adjustIndex) withString:@"..."]; // 重新设置值 textView.text = adjustText; if (attributes && adjustText) { textView.text = nil; NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:adjustText attributes:attributes]; textView.attributedText = attributeString; } } } } textFrame.size.height = [textView sizeThatFits:CGSizeMake(textFrame.size.width, MAXFLOAT)].height; textView.frame = textFrame; }
网友评论