How to display only 3 lines of content when the UILabel has a lot of content, display more after the ellipsis, and click more to add a click action

As required above, we can add a category method to UILabel,
@interface UILabel (ReadMore)

-(void)setReadMoreLabelContentMode;

@end

#import "UILabel+ReadMore.h"

#import <CoreText/CoreText.h>

@implementation UILabel (ReadMore)

-(void)setReadMoreLabelContentMode

{

    NSArray *contents = [self getLinesArrayOfLabelRows];

    if (contents.count <= 1) {

        self .userInteractionEnabled = NO ; // If a line is not displayed, view more, and cancel the gesture response.

        return;

    }

    self.userInteractionEnabled=YES;

    

    NSUInteger cutLength = 7; // The intercepted length is 20

    

    NSMutableString *contentText = [[NSMutableString alloc] init];

    for (NSInteger i = 0; i < self.numberOfLines; i++) {

        if (i == self .numberOfLines - 1) { // The last line is processed plus.....

            

            NSString *lastLineText = [NSString stringWithFormat:@"%@",contents[i]];

            NSUInteger lineLength = lastLineText.length;

            if (lineLength > cutLength) {

                lastLineText = [lastLineText substringToIndex:(lastLineText.length - cutLength)];

            }

            [contentText appendString:[NSString stringWithFormat:@"%@.....",lastLineText]];

            

        } else {

            [contentText appendString:contents[i]];

        }

    }

    

    NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];

    NSDictionary *dictionary = @{

                                 NSForegroundColorAttributeName : self.textColor,

                                 NSFontAttributeName : self.font,

                                 NSParagraphStyleAttributeName : style

                                 };

    

    NSMutableAttributedString *mutableAttribText = [[NSMutableAttributedString alloc] initWithString:[contentText stringByAppendingString:@"  更多"] attributes:dictionary];

    [mutableAttribText addAttributes:@{

                                       NSFontAttributeName : [UIFont boldSystemFontOfSize:16.0f],

                                       NSForegroundColorAttributeName : [UIColor blueColor]

                                       } range:NSMakeRange(contentText.length, 4)];

    self.attributedText = mutableAttribText;

}

// Get Label and get an array for each line of content

- (NSArray *)getLinesArrayOfLabelRows

{

    CGFloat labelWidth = self.frame.size.width;

    

    NSString *text = [self text];

    UIFont *font = [self font];

    if (text == nil) {

        return nil;

    }

    CTFontRef myFont = CTFontCreateWithName(( CFStringRef)([font fontName]), [font pointSize], NULL);

    NSMutableAttributedString *attStr = [[NSMutableAttributedString alloc] initWithString:text];

    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];

    paragraphStyle.lineBreakMode = NSLineBreakByCharWrapping;

    [attStr addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, attStr.length)];

    [attStr addAttribute:(NSString *)kCTFontAttributeName

                   value:(__bridge  id)myFont

                   range:NSMakeRange(0, attStr.length)];

    CFRelease(myFont);

    CTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString(( CFAttributedStringRef)attStr);

    CGMutablePathRef path = CGPathCreateMutable();

    CGPathAddRect(path, NULL, CGRectMake(0,0,labelWidth,100000));

    CTFrameRef frame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, 0), path, NULL);

    NSArray *lines = ( NSArray *)CTFrameGetLines(frame);

    NSMutableArray *linesArray = [[NSMutableArray alloc]init];

    for (id line in lines) {

        CTLineRef lineRef = (__bridge  CTLineRef )line;

        CFRange lineRange = CTLineGetStringRange(lineRef);

        NSRange range = NSMakeRange(lineRange.location, lineRange.length);

        NSString *lineString = [text substringWithRange:range];

        CFAttributedStringSetAttribute((CFMutableAttributedStringRef)attStr,

                                       lineRange,

                                       kCTKernAttributeName,

                                       (CFTypeRef)([NSNumber numberWithFloat:0.0]));

        CFAttributedStringSetAttribute((CFMutableAttributedStringRef)attStr,

                                       lineRange,

                                       kCTKernAttributeName,

                                       (CFTypeRef)([NSNumber numberWithInt:0.0]));

        [linesArray addObject:lineString];

    }

    CGPathRelease(path);

    CFRelease(frame);

    CFRelease(frameSetter);

    return (NSArray *)linesArray;

}

@end

Code to call this method:

- (void)viewDidLoad {

    [super viewDidLoad];

    

    NSString *context = @"When the last line is not fully displayed, it is sometimes necessary to change the position of the ellipsis. The system does not provide it. Zhang Nala invited me to her house to play for a while, then eat, watch TV, and then change the last A line of text is truncated at the specified place and then spliced ​​with ellipses";

        NSLog(@" %lu ",(unsigned long)context.length);

        

        UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10.0f, 60.0f, self.view.frame.size.width - 20.0f, 70.0f)];

        label.font = [UIFont systemFontOfSize:16.0f];

        label.numberOfLines = 3;

        [self.view addSubview:label];

        

        UITapGestureRecognizer *labelTapGestureRecognizer = [[UITapGestureRecognizer alloc]initWithTarget: self action: @selector (labelTouchUpInside)];

        [label addGestureRecognizer:labelTapGestureRecognizer];

        

        label.text = context;

        [label setReadMoreLabelContentMode];

}

-(void)labelTouchUpInside{

    NSLog(@"View more");

}

Guess you like

Origin blog.csdn.net/u013712343/article/details/135106623