简体   繁体   中英

UILabel line breaks truncate tails

I'm using storyboard to set number of lines(4) of UILabel and line breaking(truncate tails).

This is what i have right now:

在此输入图像描述

My question is how do I truncate/trigger truncate?

This is what i want to achieve:

在此输入图像描述

Update:

Just to make my question clearer.
I dont want to cut the actual string in the UILabel like how the default UILabel behaves.

The log produced by the first image when using NSLog(@"%@", myLabel.text); is the complete string assigned to it, and that is behavior i'm trying to achieve.

In my example it's:

A little girl was talking to her teacher about whales. The teacher said it was physically impossible for a whale to swallow a human because even though it was a very large mammal.

---

Making my question clearer:

How do I truncate/trigger truncate without cutting the actual NSString assigned to it?

or maybe a work around that will lead to that, this is possible right?

You can use TTTAttributedLabel library

For example :

在此输入图像描述

Declaration :

@property (strong, nonatomic) IBOutlet TTTAttributedLabel *lblTT;

Example Code with setAttributedTruncationToken :

NSDictionary *attr = @{NSForegroundColorAttributeName : [UIColor redColor]};

NSAttributedString *str = [[NSAttributedString alloc] initWithString:@"...Continue Reading" attributes:attr];

[self.lblTT setAttributedTruncationToken:str];

Hope it will help you.

If you don't want to use ready made class, Please check this answer : How to add button to the end of text like Facebook's "Continue reading"?

I use Associated Objects and Method Swizzling to implement that. Inheritance maybe better than category in this case. It's up to you.

UILabel+Display.h:

#import <UIKit/UIKit.h>

@interface UILabel (Display)

@end

UILabel+Display.m:

#import "UILabel+Display.h"
#import <objc/runtime.h>

@implementation UILabel (Display)

+ (void)initialize
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class class = [self class];
        SEL originalSelector = @selector(setText:);
        SEL swizzledSelector = @selector(setDisplayText:);
        [self swizzleeClass:class selector:originalSelector replaceSeletor:swizzledSelector];

        SEL textSelector = @selector(text);
        SEL swizzledTextSelector = @selector(originText);
        [self swizzleeClass:class selector:textSelector replaceSeletor:swizzledTextSelector];
    });
}

- (NSString *)originText
{
   return objc_getAssociatedObject(self, @selector(originText));
}

- (void)setDisplayText:(NSString *)text
{
    objc_setAssociatedObject(self, @selector(originText), text, OBJC_ASSOCIATION_COPY);
    UIFont *font = self.font;
    NSDictionary *attributes = @{NSFontAttributeName:font};
    CGRect bounds = self.bounds;
    CGFloat width = CGRectGetWidth(bounds);
    CGFloat height = CGRectGetHeight(bounds);
    CGSize maxSize = CGSizeMake(width, CGFLOAT_MAX);
    NSStringDrawingOptions drawOptions = NSStringDrawingUsesLineFragmentOrigin;
    CGRect rect = [text boundingRectWithSize:maxSize
                                     options:drawOptions
                                  attributes:attributes
                                     context:nil];
    CGFloat needHeight = CGRectGetHeight(rect);

    NSString *tipText = @" ... continue reading";
    NSUInteger index = text.length-1;
    NSString *displayText = text;
    while (needHeight>height) {
        displayText = [[text substringToIndex:index]stringByAppendingString:tipText];
        rect = [displayText boundingRectWithSize:maxSize
                                         options:drawOptions
                                      attributes:attributes
                                         context:nil];
        needHeight = CGRectGetHeight(rect);
        //needHeight = [displayText sizeWithFont:font constrainedToSize:maxSize lineBreakMode:NSLineBreakByWordWrapping].height; //NS_DEPRECATED_IOS(2_0, 7_0)
        index--;
    }
    [self setDisplayText:displayText];
}

+ (void)swizzleeClass:(Class)class selector:(SEL)originalSelector replaceSeletor:(SEL)swizzledSelector
{
    Method originalMethod = class_getInstanceMethod(class, originalSelector);
    Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);

    BOOL didAddMethod = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));

    if (didAddMethod) {
        class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
    } else {
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
}

@end

Note I don't handle short text condition and attributed string.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM