How to check if UILabel is truncated?

前端 未结 20 2575
不知归路
不知归路 2020-11-28 02:53

I have a UILabel that can be varying lengths depending on whether or not my app is running in portrait or landscape mode on an iPhone or iPad. When the text is

相关标签:
20条回答
  • 2020-11-28 03:16

    you can make a category with UILabel

    - (BOOL)isTextTruncated
    
    {
        CGRect testBounds = self.bounds;
        testBounds.size.height = NSIntegerMax;
        CGRect limitActual = [self textRectForBounds:[self bounds] limitedToNumberOfLines:self.numberOfLines];
        CGRect limitTest = [self textRectForBounds:testBounds limitedToNumberOfLines:self.numberOfLines + 1];
        return limitTest.size.height>limitActual.size.height;
    }
    
    0 讨论(0)
  • 2020-11-28 03:16

    I had issues with boundingRect(with:options:attributes:context:) when using autolayout (to set a max height) and an attributed text with NSParagraph.lineSpacing

    The spacing between lines was ignored (even when passed in attributes to the boundingRect method) so the label might be considered as not truncated when it was.

    The solution I found is to use UIView.sizeThatFits :

    extension UILabel {
        var isTruncated: Bool {
            layoutIfNeeded()
            let heightThatFits = sizeThatFits(bounds.size).height
            return heightThatFits > bounds.size.height
        }
    }
    
    0 讨论(0)
  • 2020-11-28 03:24

    Use this category to find if a label is truncated on iOS 7 and above.

    // UILabel+Truncation.h
    @interface UILabel (Truncation)
    
    @property (nonatomic, readonly) BOOL isTruncated;
    
    @end
    
    
    // UILabel+Truncation.m
    @implementation UILabel (Truncation)
    
    - (BOOL)isTruncated
    {
        CGSize sizeOfText =
          [self.text boundingRectWithSize:CGSizeMake(self.bounds.size.width, CGFLOAT_MAX)
                                   options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading)
                                attributes:@{ NSFontAttributeName : label.font } 
                                   context: nil].size;
    
        if (self.frame.size.height < ceilf(sizeOfText.height))
        {
            return YES;
        }
        return NO;
    }
    
    @end
    
    0 讨论(0)
  • 2020-11-28 03:24

    Here's the selected answer in Swift 3 (as an extension). The OP was asking about 1 line labels. Many of the swift answers I tried here are specific to multi-line labels and aren't flagging correctly on single line labels.

    extension UILabel {
        var isTruncated: Bool {
            guard let labelText = text as? NSString else {
                return false
            }
            let size = labelText.size(attributes: [NSFontAttributeName: font])
            return size.width > self.bounds.width
        }
    }
    
    0 讨论(0)
  • 2020-11-28 03:24

    To add to what @iDev did, I modified the self.frame.size.height to use label.frame.size.height and also did not use NSStringDrawingUsesLineFontLeading. After those modifications, I achieved perfect calculation of when the truncation would happen (at least for my case).

    - (BOOL)isTruncated:(UILabel *)label {
        CGSize sizeOfText = [label.text boundingRectWithSize: CGSizeMake(label.bounds.size.width, CGFLOAT_MAX)
                                                     options: (NSStringDrawingUsesLineFragmentOrigin)
                                                  attributes: [NSDictionary dictionaryWithObject:label.font forKey:NSFontAttributeName] context: nil].size;
    
        if (label.frame.size.height < ceilf(sizeOfText.height)) {
            return YES;
        }
        return NO;
    }
    
    0 讨论(0)
  • 2020-11-28 03:27

    You can calculate the width of the string and see if the width is greater than label.bounds.size.width

    NSString UIKit Additions has several methods for computing the size of the string with a specific font. However, if you have a minimumFontSize for your label that allows the system to shrink the text down to that size. You may want to use sizeWithFont:minFontSize:actualFontSize:forWidth:lineBreakMode: in that case.

    CGSize size = [label.text sizeWithAttributes:@{NSFontAttributeName:label.font}];
    if (size.width > label.bounds.size.width) {
       ...
    }
    
    0 讨论(0)
提交回复
热议问题