iOS Label最后一行显示不全,添加展开

label.png

当最后一行显示不全时,需求有时候需要改变省略号的位置,系统并未提供,但我们可以通过 coreText 拿到每行的文字,然后将最后一行文字在指定的地方截断,再拼接省略号,话不多说,贴代码:

FXBreakLineLable.h

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface FXBreakLineLable : UILabel

- (void)setLineBreakByTruncatingLastLine;

@end

NS_ASSUME_NONNULL_END

FXBreakLineLable.m

#import "FXBreakLineLable.h"
#import <CoreText/CoreText.h>

@implementation FXBreakLineLable

- (void)setLineBreakByTruncatingLastLine {
    
    if ( self.numberOfLines <= 0 ) {
        return;
    }
    NSArray *separatedLines = [self getSeparatedLinesArray];
    
    NSMutableString *limitedText = [NSMutableString string];
    if ( separatedLines.count >= self.numberOfLines ) {
        
        for (int i = 0 ; i < self.numberOfLines; i++) {
            if ( i == self.numberOfLines - 1) {
                FXBreakLineLable *lastLineLabel = [[FXBreakLineLable alloc]initWithFrame:CGRectMake(0, 0, self.frame.size.width - 100, MAXFLOAT)];
                lastLineLabel.font = self.font;
                lastLineLabel.text = separatedLines[self.numberOfLines - 1];
                
                NSArray *subSeparatedLines = [lastLineLabel getSeparatedLinesArray];
                NSString *lastLineText = [subSeparatedLines firstObject];
                NSInteger lastLineTextCount = lastLineText.length;
                if ([[lastLineText substringFromIndex:(lastLineTextCount - 1)] isEqualToString:@"\n"]) {
                    lastLineText = [lastLineText substringToIndex:(lastLineText.length - 1)];
                    lastLineTextCount = lastLineTextCount - 1;
                }
                [limitedText appendString:[NSString stringWithFormat:@"%@...",[lastLineText substringToIndex:lastLineTextCount]]];
            } else {
                [limitedText appendString:separatedLines[i]];
            }
        }
        
        
    } else {
        [limitedText appendString:self.text];
    }
    
    NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
    style.lineSpacing = 7;
    NSMutableAttributedString *attText = [[NSMutableAttributedString alloc] initWithString: (( separatedLines.count >= self.numberOfLines ) ? [limitedText stringByAppendingString:@"   全文"] : limitedText)
                                                                       attributes:@{
                                                                                    NSForegroundColorAttributeName : self.textColor,
                                                                                    NSFontAttributeName : self.font,
                                                                                    NSParagraphStyleAttributeName : style
                                                                                    }];
    if ( separatedLines.count >= self.numberOfLines ) {
        [attText addAttributes:@{
                                NSFontAttributeName : [UIFont boldSystemFontOfSize:14.0],
                                NSForegroundColorAttributeName : [UIColor blackColor]
                                } range:NSMakeRange(attText.length - 2, 2)];
    }
    
    self.attributedText = attText;
}

- (NSArray *)getSeparatedLinesArray {
    NSString *text = [self text];
    UIFont   *font = [self font];
    
    CTFontRef myFont = CTFontCreateWithName((__bridge CFStringRef)([font fontName]), [font pointSize], NULL);
    NSMutableAttributedString *attStr = [[NSMutableAttributedString alloc] initWithString:text];
    [attStr addAttribute:(NSString *)kCTFontAttributeName value:(__bridge id)myFont range:NSMakeRange(0, attStr.length)];
    
    CTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)attStr);
    
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathAddRect(path, NULL, CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width - 55, 100000));
    
    CTFrameRef frame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, 0), path, NULL);
    
    NSArray *lines = (__bridge 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];
        [linesArray addObject:lineString];
    }
       
    return (NSArray *)linesArray;
}

@end

当前需求是在后端显示 “全文” 二字,其他需求实现需要稍作修改;