I have a multi-line UILabel
(numberOfLines
= 0). It\'s width can change at runtime, and sometimes this leads to truncation and/or re-wrapping. Some
Use this method to find lable truncated in 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;
}
The answer above is using a depreciated method, so i thought the following code could be useful:
- (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;
}
Swift 3 solution
You can count the number of lines after assigning the string and compare to the max number of lines of the label.
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
}
}
For versions higher than iOS 7, you can check the following solutions:
You could know the size of label that is needed to display a particular NSString
instance. For example, you could use that one:
- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size lineBreakMode:(UILineBreakMode)lineBreakMode
Returns the size of the string if it were rendered with the specified constraints.
So what you want is to get CGSize
for a particular string and check if it is not larger then UILabel
size:
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");
}
More useful NSString
methods you could find here: NSString UIKit Additions Reference
Ok, another way of doing what you want:
1) Create 2 UILabel
with the same properties but second one (label2
) will be with another one width
.
2) Set alpha
property of label2
to 0.0
in non-edit mode.
3) When edit mode begins make such animation:
// label1.alpha == 1.0, label2.alpha == 0.0
{[UIView animateWithDuration:0.5 animations:^{
label1.alpha = 0.0;
label2.alpha = 1.0;
}];
4) When edit mode ends:
{[UIView animateWithDuration:0.5 animations:^{
label1.alpha = 1.0;
label2.alpha = 0.0;
}];
That will give you the same result as in Mail.app