是否可以让UILabel
由多个\n
分隔的行组成,以使其行宽为>标签宽度是否被截断而未被包裹?
假设我有一些如下文字:
我希望它出现在我的UILabel
中,如此:
1. This is a really long first line of text... 2. Short line 3. Another short line
然而,正在发生的事情是我得到了这个:
1. This is a really long first line of text that is too long to fit horizontally 2. Short line...
第三条线被切断了。我已将行数设置为3
,但它仍然包裹第一个长行。我在标签上设置换行符属性似乎并不重要 - 它总是包装第一行。有没有办法防止完全包裹在标签上?
答案 0 :(得分:3)
我不认为您可以应用于标签的任何设置都可以实现。一种方法是将字符串分成单独的行,截断任何需要它的行,使它(带有一个附加的省略号)适合一行,然后将字符串放回到一起使用换行符。这样的东西应适用于任意数量的行,
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UILabel *label;
@property (nonatomic) CGFloat ellipsisWidth;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSString *text = @"This is a really long first line of text that is too long to fit horizontally\nShort line\nAnother short line";
NSString *ellipsis = @"...";
self.ellipsisWidth = [ellipsis sizeWithAttributes:@{NSFontAttributeName:self.label.font}].width;
__block NSMutableString *truncatedString = [@"" mutableCopy];
[text enumerateLinesUsingBlock:^(NSString *line, BOOL *stop) {
[truncatedString appendFormat:@"%@\n", [self oneLineOfString:line withFont:self.label.font]];
}];
NSString *finalString = [truncatedString stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
self.label.numberOfLines = 0;
self.label.text = finalString;
}
-(NSString *)oneLineOfString:(NSString *) aLine withFont:(UIFont *) font {
__block NSString *singleLine = nil;
__block NSString *lastFragment;
[aLine enumerateSubstringsInRange:NSMakeRange(0, aLine.length) options:NSStringEnumerationByWords usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
NSString *textFragment = [aLine substringToIndex:(substringRange.location + substringRange.length)];
CGRect textRect = [textFragment boundingRectWithSize:CGSizeMake(CGFLOAT_MAX ,CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:font} context:nil];
if (textRect.size.width >= self.label.bounds.size.width - self.ellipsisWidth) {
singleLine = [lastFragment stringByAppendingString:@"..."];
*stop = YES;
}
lastFragment = textFragment;
}];
if (!singleLine) singleLine = aLine; // it doesn't need to be truncated, so return the passed in line
return singleLine;
}
如果要按字符而不是按字词截断,可以将NSStringEnumerationByComposedCharacterSequences而不是NSStringEnumerationByWords传递给options参数 enumerateSubstringsInRange:选择:usingBlock:
当然,你可以轻松地做到这一点;将3个标签堆叠在一起,并为每个标签添加一行文字:)