如何判断一个UILabel将被截断和/或其换行符位置将会改变
我有一个多行UILabel
( numberOfLines
= 0)。 它的宽度可以在运行时改变,有时会导致截断和/或重新包装。 一些例子说明了这一点:
示例1:宽度的减小导致不同的折线点
例2:宽度的减less导致截断
示例3:宽度的减小导致截断和不同的换行符位置
示例4:宽度的减小对截断或换行位置没有任何影响
由于这种格式的变化可能会相当刺耳,我打算在一些animation背后隐藏它(可能是淡入/淡出)。 但是,第一个障碍是确定何时需要这样做。 我不想在标签重新resize时应用animation – 只有当它会导致截断或换行符位置发生变化时。
我该如何testing呢? 例如,testing应返回“是”,例如1,2和3,否则返回例如4。
注意:resize不会改变我的例子中的行数。
注2:如果有人有更好的标签相关的文字格式我很想知道他们 – 随时编辑。
注3:如果你有兴趣看到这种行为完成,请尝试苹果的iPhone上的mail.app。 查看收件箱时,轻扫一封电子邮件并观看摘要行淡入/淡出,因为它重新包装和/或截断(但不是当不需要时)。
您可以知道显示特定NSString
实例所需的标签大小。 例如,你可以使用那个:
- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size lineBreakMode:(UILineBreakMode)lineBreakMode
如果使用指定的约束呈现string,则返回string的大小。
所以你想要的是为特定的string获取CGSize
,并检查它是否不大于UILabel
大小:
UILabel *label; CGSize sizeNeeded = [label.text sizeWithFont:label.font constrainedToSize:CGSizeMake(label.bounds.size.width, MAXFLOAT)]; if (sizeNeeded.height > label.bounds.size.height) { NSLog(@"String is truncated"); }
更有用的NSString
方法,你可以在这里find: NSString UIKit Additions Reference
好吧,做你想做的另一种方式:
1)创build2个具有相同属性的UILabel
,但是第二个( label2
)将具有另一个width
。
2)在非编辑模式下将label2
alpha
属性设置为0.0
。
3)编辑模式开始时,进行这样的animation:
// label1.alpha == 1.0, label2.alpha == 0.0 {[UIView animateWithDuration:0.5 animations:^{ label1.alpha = 0.0; label2.alpha = 1.0; }];
4)编辑模式结束时:
{[UIView animateWithDuration:0.5 animations:^{ label1.alpha = 1.0; label2.alpha = 0.0; }];
这会给你在Mail.app相同的结果
Swift 3解决scheme
您可以在分配string之后计算行数,并与标签的最大行数进行比较。
import Foundation import UIKit extension UILabel { func countLabelLines() -> Int { // Call self.layoutIfNeeded() if your view is uses auto layout let myText = self.text! as NSString let attributes = [NSFontAttributeName : self.font] let labelSize = myText.boundingRect(with: CGSize(width: self.bounds.width, height: CGFloat.greatestFiniteMagnitude), options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: attributes, context: nil) return Int(ceil(CGFloat(labelSize.height) / self.font.lineHeight)) } func isTruncated() -> Bool { if (self.countLabelLines() > self.numberOfLines) { return true } return false } }
上面的答案是使用折旧方法,所以我认为下面的代码可能是有用的:
- (BOOL)isLabelTruncated:(UILabel *)label { BOOL isTruncated = NO; CGRect labelSize = [label.text boundingRectWithSize:CGSizeFromString(label.text) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : label.font} context:nil]; if (labelSize.size.width / labelSize.size.height > label.numberOfLines) { isTruncated = YES; } return isTruncated; }
使用这个方法来查找标签在iOS 7中截断。
- (BOOL)isTruncated:(UILabel *)label{ CGSize sizeOfText = [label.text boundingRectWithSize: CGSizeMake(label.bounds.size.width, CGFLOAT_MAX) options: (NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) attributes: [NSDictionary dictionaryWithObject:label.font forKey:NSFontAttributeName] context: nil].size; if (self.frame.size.height < ceilf(sizeOfText.height)) { return YES; } return NO; }
对于高于iOS 7的版本,您可以检查以下解决scheme: