这是我的目标:
有什么想法吗?
答案 0 :(得分:1)
- (CGFloat)textViewHeightForAttributedText:(NSAttributedString*)text andWidth:(CGFloat)width
{
UITextView *calculationView = [[UITextView alloc] init];
[calculationView setAttributedText:text];
CGSize size = [calculationView sizeThatFits:CGSizeMake(width, FLT_MAX)];
return size.height;
}
- (void)viewDidLoad
{
// Invoke super
[super viewDidLoad];
// Get text of unknown length
NSMutableAttributedString *myAttributedString = [[NSMutableAttributedString alloc] initWithString:@"String of unknown length here..." attributes:@{NSForegroundColorAttributeName : [UIColor redColor]}];
// Get ellipsis w/ matching attributes
NSDictionary *endCharAttributes = [myAttributedString attributesAtIndex:myAttributedString.length - 1 effectiveRange:NULL];
NSAttributedString *ellipsis = [[NSAttributedString alloc] initWithString:@"..." attributes:endCharAttributes];
// Define size constraints
CGFloat maxHeight = 60;
CGFloat fixedWidth = 300;
// Get starting height
CGFloat textViewHeight = [self textViewHeightForAttributedText:myAttributedString andWidth:fixedWidth];
// Reduce string size and add ellipsis until we fit within our height constraint
while (textViewHeight > maxHeight)
{
NSLog(@"%f", textViewHeight);
NSRange substringRange = {0, myAttributedString.length - 6}; // Reducing by 6 works for my app (strings are never huge)
myAttributedString = [[NSMutableAttributedString alloc] initWithAttributedString:[myAttributedString attributedSubstringFromRange:substringRange]];
[myAttributedString appendAttributedString:ellipsis];
NSLog(@"myAttributedString = %@", myAttributedString);
textViewHeight = [self textViewHeightForAttributedText:myAttributedString andWidth:fixedWidth];
}
// Init and config UITextView
UITextView *textView = [[UITextView alloc] init];
textView.attributedText = myAttributedString;
textView.frame = CGRectMake(0, 0, fixedWidth, textViewHeight);
[self.view addSubview:textView];
}
有更优雅的解决方案吗?发布吧!
更新:您可以通过添加帮助程序类并实现以下类方法来提高- (CGFloat)textViewHeightForAttributedText:(NSAttributedString*)text andWidth:(CGFloat)width
的性能:
// Private, gets us to alloc init calculation view one time for life of application
+ (UITextView *)calculationView
{
static UITextView *_calculationView;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_calculationView = [[UITextView alloc] init];
});
return _calculationView;
}
// Public, app calls this a lot
+ (CGFloat)textViewHeightForAttributedText:(NSAttributedString*)text andWidth:(CGFloat)width usingUIEdgeInset:(UIEdgeInsets)edgeInsets
{
[self calculationView].textContainerInset = edgeInsets;
[self calculationView].attributedText = text;
CGSize size = [[self calculationView] sizeThatFits:CGSizeMake(width, FLT_MAX)];
return size.height;
}
答案 1 :(得分:0)
您是否考虑过继承UILabel并添加选择和复制文本的功能? Mattt Thompson有一个很好的例子here。
答案 2 :(得分:0)
我的解决方案是
- (NSString*)stringByTruncatingToWidth:(CGFloat)width maxHeight:(CGFloat)maxHeight font:(UIFont *)font;
{
NSString *ellipsis = @"…";
NSMutableString *truncatedString = [self mutableCopy];
if ([self textSizeForMaxWidth:width font:font].height > maxHeight)
{
truncatedString = [[truncatedString stringByAppendingString:ellipsis] mutableCopy];
NSRange range = {truncatedString.length - 4, 1};
[truncatedString deleteCharactersInRange:range];
while ([truncatedString textSizeForMaxWidth:width font:font].height > maxHeight){
[truncatedString deleteCharactersInRange:range];
range.location--;
}
}
return truncatedString;
}
帮助计算最大宽度
的文字大小的方法- (CGSize)textSizeForMaxWidth:(CGFloat)width font:(UIFont *)font
{
NSTextStorage *textStorage = [[NSTextStorage alloc]
initWithString:self];
NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize: CGSizeMake(width, MAXFLOAT)];
NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
[layoutManager addTextContainer:textContainer];
[textStorage addLayoutManager:layoutManager];
[textStorage addAttribute:NSFontAttributeName value:font
range:NSMakeRange(0, [textStorage length])];
[textContainer setLineFragmentPadding:0.0];
[layoutManager glyphRangeForTextContainer:textContainer];
CGRect frame = [layoutManager usedRectForTextContainer:textContainer];
return frame.size;
}