Calculate the range of visible text in UILabel

后端 未结 4 2209
鱼传尺愫
鱼传尺愫 2020-12-11 20:43

I have an UILabel with fixed size, the text that I set into this UILabel can be 200, 5 or 500 characters long. What I want to do is to calculate ho

4条回答
  •  陌清茗
    陌清茗 (楼主)
    2020-12-11 21:00

    So I've created a method which returns the current visible string height (with the size of the UITextView / UITextField or UILabel) and it's also support iOS6+, this is what I did:

    - (NSUInteger)fitString:(NSString *)string intoLabel:(UILabel *)label
    {
        UIFont *font           = label.font;
        NSLineBreakMode mode   = label.lineBreakMode;
    
        CGFloat labelWidth     = label.frame.size.width;
        CGFloat labelHeight    = label.frame.size.height;
        CGSize  sizeConstraint = CGSizeMake(labelWidth, CGFLOAT_MAX);
    
        if (SYSTEM_VERSION_GREATER_THAN(iOS_7))
        {
            NSDictionary *attributes = @{ NSFontAttributeName : font };
            NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:string attributes:attributes];
            CGRect boundingRect = [attributedText boundingRectWithSize:sizeConstraint options:NSStringDrawingUsesLineFragmentOrigin context:nil];
            {
                if (boundingRect.size.height > labelHeight)
                {
                    NSUInteger index = 0;
                    NSUInteger prev;
                    NSCharacterSet *characterSet = [NSCharacterSet whitespaceAndNewlineCharacterSet];
    
                    do
                    {
                        prev = index;
                        if (mode == NSLineBreakByCharWrapping)
                            index++;
                        else
                            index = [string rangeOfCharacterFromSet:characterSet options:0 range:NSMakeRange(index + 1, [string length] - index - 1)].location;
                    }
    
                    while (index != NSNotFound && index < [string length] && [[string substringToIndex:index] boundingRectWithSize:sizeConstraint options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil].size.height <= labelHeight);
    
                    return prev;
                }
            }
        }
        else
        {
            if ([string sizeWithFont:font constrainedToSize:sizeConstraint lineBreakMode:mode].height > labelHeight)
            {
                NSUInteger index = 0;
                NSUInteger prev;
                NSCharacterSet *characterSet = [NSCharacterSet whitespaceAndNewlineCharacterSet];
    
                do
                {
                    prev = index;
                    if (mode == NSLineBreakByCharWrapping)
                        index++;
                    else
                        index = [string rangeOfCharacterFromSet:characterSet options:0 range:NSMakeRange(index + 1, [string length] - index - 1)].location;
                }
    
                while (index != NSNotFound && index < [string length] && [[string substringToIndex:index] sizeWithFont:font constrainedToSize:sizeConstraint lineBreakMode:mode].height <= labelHeight);
    
                return prev;
            }
        }
    
        return [string length];
    }
    

    Of course that SYSTEM_VERSION_GREATER_THAN(iOS_7) are both macros that I defined. You also should define your own.

    Best of luck!

提交回复
热议问题