zoukankan      html  css  js  c++  java
  • 完美解决 向UILable 文字最后插入N张图片,支持向限制行数的UILable 最后一行插入,多余文字显示...

    效果:

    ====直接上代码吧===

    //
    //  UILabel+StringFrame.h
    //  QYER
    //
    //  Created by qyer on 15/3/19.
    //  Copyright (c) 2015年 QYER. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    
    /**
     *  uilable 行间距高度
     */
    static CGFloat const lineSapceHeight = 5.0f;
    
    @interface UILabel (StringFrame)
    
    #pragma mark - 获取UILable Size
    
    - (CGSize)boundingRectWithSize:(CGSize)size;
    /**
     *  根据文字长度计算大小
     *
     *  @param content 文字长度
     *  @param pFont   文字字号
     *  @param pWidth  宽度
     *
     */
    +(CGSize)getContentSize:(NSString *)content font:(UIFont *)pFont (CGFloat)pWidth;
    /**
     *  根据文字长度计算大小
     *
     *  @param content 文字长度
     *  @param pFont   文字字号
     *  @param pHeight  高度
     *
     */
    +(CGSize)getContentSize:(NSString *)content font:(UIFont *)pFont height:(CGFloat)pHeight;
    /**
     *  根据文本获取size ,有最大 宽高限制
     *
     *  @param string    文本
     *  @param maxWidth  最大宽
     *  @param maxHeight 最大高
     *  @param font      字体
     *  @param lineSpace 行间距(如果使用默认的,就传nil)
     *
     *  @return size
     */
    +(CGSize)getContentSizeWithContentText:(NSString *)string andMaxWidth:(CGFloat)maxWidth andMaxHeight:(CGFloat)maxHeight AndFont:(UIFont*)font andLineSpacing:(NSNumber *)lineSpace;
    /**
     *  根据文本获取size ,有最大 宽高限制
     *
     *  @param string    文本
     *  @param maxWidth  最大宽
     *  @param maxHeight 最大高
     *  @param attribute 富文本属性
     *
     *  @return size
     */
    +(CGSize)getContentSizeWithContentText:(NSString *)string andMaxWidth:(CGFloat)maxWidth andMaxHeight:(CGFloat)maxHeight andAttributes:(NSDictionary *)attribute;
    
    
    #pragma mark - 获取UILable 每行显示的文字
    
    /**
     *  获取lalbe 每行文字
     *
     *  @return 每行文字数组
     */
    - (NSArray *)getSeparatedLines;
    /**
     *  获取lalbe 每行文字
     *
     *  @param text 根据文字内容
     *
     *  @return 每行文字数组
     */
    - (NSArray *)getSeparatedLinesWithText:(NSString*)text;
    /**
     *  获取lalbe 每行文字
     *
     *  @param content 文字内容
     *  @param fonte   fonte description
     *  @param size    size description
     *
     *  @return return value description
     */
    +(NSArray *)getSeparatedLinesWithText:(NSString*)content andFonte:(UIFont *)fonte andSize:(CGSize)size;
    
    
    #pragma mark - 完美解决 向UILable 文字最后插入N张图片,支持向限制行数的UILable 最后一行插入,多余文字显示...
    
    /**
     *  向文字末尾追加图片,适用于已知Size的UILable
     *
     *  @param contentStr 文字内容
     *  @param imgs       插入的图片数组, 图片最好带间隔哦
     */
    -(void)insertImgToContentLast:(NSString *)contentStr imgs:(NSArray *)imgs;
    /**
     *  向文字末尾追加图片,适用于AutoLayout 的UILable
     *
     *  @param contentStr    文字内容
     *  @param imgs          插入的图片数组, 图片最好带间隔哦
     *  @param estimateWidth 预估的UILable 最大宽度(已知的最大宽度)
     */
    -(void)insertImgToContentLast:(NSString *)contentStr imgs:(NSArray *)imgs estimateWidth:(CGFloat)estimateWidth;
    /**
     *  向已知文字后插入图片
     *
     *  @param insertImgArr           insertImgArr description
     *  @param appendAttributedString 可为nil
     */
    -(void)configTitleLableAttributedString:(NSArray *)insertImgArr AttributedString:(NSMutableAttributedString *)appendAttributedString;
    
    @end
    //
    //  UILabel+StringFrame.m
    //  QYER
    //
    //  Created by qyer on 15/3/19.
    //  Copyright (c) 2015年 QYER. All rights reserved.
    //
    
    #import "UILabel+StringFrame.h"
    
    #import <CoreText/CoreText.h>
    
    @implementation UILabel (StringFrame)
    
    #pragma mark - 获取UILable Size
    
    - (CGSize)boundingRectWithSize:(CGSize)size
    {
        NSDictionary *attribute = @{NSFontAttributeName: self.font};
        
        CGSize retSize = [self.text boundingRectWithSize:size
                                                 options:
                          NSStringDrawingTruncatesLastVisibleLine |
                          NSStringDrawingUsesLineFragmentOrigin |
                          NSStringDrawingUsesFontLeading
                                              attributes:attribute
                                                 context:nil].size;
        
        return retSize;
    }
    
    +(CGSize)getContentSize:(NSString *)content font:(UIFont *)pFont (CGFloat)pWidth{
        
        CGSize contentSize;
        if (ios7) {
            contentSize = [content boundingRectWithSize:CGSizeMake(pWidth, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:[NSDictionary dictionaryWithObjectsAndKeys:pFont,NSFontAttributeName, nil] context:nil].size;
        }else{
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Wdeprecated-declarations"
            contentSize = [content sizeWithFont:pFont constrainedToSize:CGSizeMake(pWidth, MAXFLOAT) lineBreakMode:NSLineBreakByCharWrapping];
    #pragma clang diagnostic pop
    
        }
        return contentSize;
    }
    
    +(CGSize)getContentSize:(NSString *)content font:(UIFont *)pFont height:(CGFloat)pHeight{
        
        CGSize contentSize;
        if (ios7) {
            contentSize = [content boundingRectWithSize:CGSizeMake(MAXFLOAT, pHeight) options:NSStringDrawingUsesLineFragmentOrigin attributes:[NSDictionary dictionaryWithObjectsAndKeys:pFont,NSFontAttributeName, nil] context:nil].size;
        }else{
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Wdeprecated-declarations"
            contentSize = [content sizeWithFont:pFont constrainedToSize:CGSizeMake(MAXFLOAT, pHeight) lineBreakMode:NSLineBreakByCharWrapping];
    #pragma clang diagnostic pop
    
        }
        return contentSize;
    }
    
    /**
    *  根据文本获取size ,有最大 宽高限制
    *
    *  @param string    文本
    *  @param maxWidth  最大宽
    *  @param maxHeight 最大高
    *  @param attribute 富文本属性
    *
    *  @return size
    */
    +(CGSize)getContentSizeWithContentText:(NSString *)string andMaxWidth:(CGFloat)maxWidth andMaxHeight:(CGFloat)maxHeight  andAttributes:(NSDictionary *)attribute{
        CGSize size = CGSizeZero;
        if (IsEmpty(string)) {
            return size;
        }
        if (string) {
            if ([string respondsToSelector:
                 @selector(boundingRectWithSize:options:attributes:context:)]) {
                size = [string boundingRectWithSize:CGSizeMake(maxWidth, maxHeight)
                                            options:NSStringDrawingUsesLineFragmentOrigin| NSStringDrawingTruncatesLastVisibleLine |NSStringDrawingUsesFontLeading
                                         attributes:attribute
                                            context:nil].size;
            }else {
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Wdeprecated-declarations"
                size = [string sizeWithFont:attribute[@"NSFontAttributeName"]
                          constrainedToSize:CGSizeMake(maxWidth, maxHeight)
                              lineBreakMode:NSLineBreakByCharWrapping];
    #pragma clang diagnostic pop
            }
        }
        if (!CGSizeEqualToSize(CGSizeZero, size)) {
            
            CGFloat wight = maxWidth;
            CGFloat height = ceil(size.height);
            /**
             *  使用 NIAttributedLabel 有个bug ,当文字只有一行或不满一行 会出现文字显示不出来
             */
            if (!attribute) {
                NSArray *rows = [UILabel getSeparatedLinesWithText:string  andFonte:attribute[NSFontAttributeName] andSize:size];
                if ([rows count]==1) {
                    CGSize offsetSize = [UILabel getContentSize:string font:attribute[NSFontAttributeName] maxWidth];
                    size = CGSizeMake(ceil(offsetSize.width) , ceil(offsetSize.height));
                }else{
                    size = CGSizeMake(wight ,height);
                }
            }else {
                size = CGSizeMake(wight ,height);
            }
        }
        return size;
    }
    
    
    /**
     *  根据文本获取size ,有最大 宽高限制
     *
     *  @param string    文本
     *  @param maxWidth  最大宽
     *  @param maxHeight 最大高
     *  @param font      字体
     *  @param lineSpace 行间距(如果使用默认的,就传nil)
     *
     *  @return size
     */
    +(CGSize)getContentSizeWithContentText:(NSString *)string andMaxWidth:(CGFloat)maxWidth andMaxHeight:(CGFloat)maxHeight AndFont:(UIFont*)font andLineSpacing:(NSNumber *)lineSpace{
        CGSize size = CGSizeZero;
        if (IsEmpty(string)) {
            return size;
        }
        if (string && font) {
            if ([string respondsToSelector:
                 @selector(boundingRectWithSize:options:attributes:context:)]) {
                NSMutableParagraphStyle * paragraphStyle = [[NSMutableParagraphStyle alloc] init];
                paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
                paragraphStyle.alignment = NSTextAlignmentLeft;
                if (lineSpace) {
                    paragraphStyle.lineSpacing = [lineSpace floatValue];
                }
                size = [string boundingRectWithSize:CGSizeMake(maxWidth, maxHeight)
                                            options:NSStringDrawingUsesLineFragmentOrigin| NSStringDrawingTruncatesLastVisibleLine |NSStringDrawingUsesFontLeading
                                         attributes:@{NSFontAttributeName:font,
                                                      NSParagraphStyleAttributeName:paragraphStyle}
                                            context:nil].size;
                
            }else {
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Wdeprecated-declarations"
                size = [string sizeWithFont:font
                          constrainedToSize:CGSizeMake(maxWidth, maxHeight)
                              lineBreakMode:NSLineBreakByCharWrapping];
    #pragma clang diagnostic pop
            }
        }
        if (!CGSizeEqualToSize(CGSizeZero, size)) {
            
            CGFloat wight = ceil(maxWidth);
            CGFloat height = ceil(size.height );
            
            /**
             *  使用 NIAttributedLabel 有个bug ,当文字只有一行或不满一行 会出现文字显示不出来
             */
            NSArray *rows = [UILabel getSeparatedLinesWithText:string  andFonte:font andSize:size];
            if ([rows count]==1) {
                CGSize offsetSize = [UILabel getContentSize:string font:font maxWidth];
                size = CGSizeMake(ceil(offsetSize.width) , ceil(offsetSize.height));
            }else{
                size = CGSizeMake(wight ,height);
            }
            
        }
        return size;
    }
    
    #pragma mark - 获取UILable 每行显示的文字
    
    /**
     *  获取lalbe 每行文字
     *
     *  @return 每行文字数组
     */
    - (NSArray *)getSeparatedLines {
        return [self getSeparatedLinesWithText:self.text];
    }
    
    /**
     *  获取lalbe 每行文字
     *
     *  @param text 根据文字内容
     *
     *  @return 每行文字数组
     */
    - (NSArray *)getSeparatedLinesWithText:(NSString*)text
    {
        /**
         *  fix NSConcreteMutableAttributedString initWithString:: nil value
         */
        if (!(text && [text isKindOfClass:[NSString class]])) {
            return nil;
        }
        
        return [UILabel getSeparatedLinesWithText:text andFonte:[self font] andSize:[self frame].size];
    }
    
    /**
     *  获取lalbe 每行文字
     *
     *  @param content 文字内容
     *  @param fonte   fonte description
     *  @param size    size description
     *
     *  @return 每行文字数组
     */
    +(NSArray *)getSeparatedLinesWithText:(NSString*)content andFonte:(UIFont *)fonte andSize:(CGSize)size{
        if (!(content&&[content isKindOfClass:[NSString class]]) ||
            !(fonte&& [fonte isKindOfClass:[UIFont class]]) ||
            CGSizeEqualToSize(CGSizeZero, size)) {
            return nil;
        }
        NSString *text = content;
        UIFont   *font = fonte;
        CGRect    rect = CGRectMake(0, 0, size.width,size.height);
        
        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,rect.size.width,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];
        }
        
        CFRelease(frameSetter);
        CFRelease(myFont);
        CFRelease(frame);
        CFRelease(path);
        
        return (NSArray *)linesArray;
    }
    
    #pragma mark - 完美解决 向UILable 文字最后插入N张图片,支持向限制行数的UILable 最后一行插入,多余文字显示...
    
    /**
     *  向文字末尾追加图片,适用于已知Size的UILable
     *
     *  @param contentStr 文字内容
     *  @param imgs       插入的图片数组, 图片最好带间隔哦
     */
    -(void)insertImgToContentLast:(NSString *)contentStr imgs:(NSArray *)imgs{
        if (IsEmpty(contentStr) || !imgs || [imgs count] == 0) {
            self.text = IsEmpty(contentStr)?@"":contentStr;
            return ;
        }
        
        [self insertImgToContentLast:contentStr imgs:imgs estimateWidth:[self frame].size.width];
    }
    /**
     *  向文字末尾追加图片,适用于AutoLayout 的UILable
     *
     *  @param contentStr    文字内容
     *  @param imgs          插入的图片数组, 图片最好带间隔哦
     *  @param estimateWidth 预估的UILable 最大宽度(已知的最大宽度)
     */
    -(void)insertImgToContentLast:(NSString *)contentStr imgs:(NSArray *)imgs estimateWidth:(CGFloat)estimateWidth{
        if (IsEmpty(contentStr) || !imgs || [imgs count] == 0 || estimateWidth == 0) {
            self.text = IsEmpty(contentStr)?@"":contentStr;
            return ;
        }
    
        //获取每行文字需要预设宽度,不然每个字都会是单独的一行
        self.width = estimateWidth;
        NSArray *textLineArr =  [self getSeparatedLinesWithText:contentStr];
        NSInteger maxLine = self.numberOfLines;
        
        if (maxLine ==  0) {
            self.text = contentStr;
            //追加图片
            [self configTitleLableAttributedString:imgs AttributedString:nil];
            return;
        }
        NSInteger lastLineIndex = maxLine - 1;
    
        if ([textLineArr count] <= lastLineIndex) {
            self.text = contentStr;
            //追加图片
            [self configTitleLableAttributedString:imgs AttributedString:nil];
            return;
        }
        
        __block CGFloat imgWith = 0.0;
        [imgs enumerateObjectsUsingBlock:^(UIImage* img, NSUInteger idx, BOOL * _Nonnull stop) {
            imgWith += img.size.width;
        }];
        
        CGFloat lastTextMaxWith = estimateWidth - imgWith;
        if (lastTextMaxWith <= 0) {
            self.text = contentStr;
            //追加图片
            [self configTitleLableAttributedString:imgs AttributedString:nil];
            return ;
        }
    
        if ([textLineArr count] > lastLineIndex) {
            NSMutableString *muShowTitle = [NSMutableString string];
            [textLineArr enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                if (idx > (lastLineIndex - 1)) {
                    //预设宽度
                    self.width = lastTextMaxWith;
                    //最大宽带下能显示的字数
                    NSArray *lastLineArr = [self getSeparatedLinesWithText:textLineArr[lastLineIndex]];
                    NSString *lastLineText = lastLineArr[0];
                    //                DDLogDebug(@"====lastLineText=======%@==",lastLineText);
                    if ([lastLineArr count] > 1) {
                        lastLineText = [lastLineText stringByReplacingCharactersInRange:NSMakeRange(lastLineText.length - 3, 3) withString:@"..."];
                    }
                    //                DDLogDebug(@"====lastLineArr[0]=======%@==",lastLineText);
                    [muShowTitle appendString:lastLineText];
                    
                    * stop = YES;
                    return ;
                }
                [muShowTitle appendString:textLineArr[idx]];
            }];
            self.text = muShowTitle;
    //        self.width = estimateWidth;
        }
    
        //追加图片
        [self configTitleLableAttributedString:imgs AttributedString:nil];
    }
    
    /**
     *  向已知文字后插入图片
     *
     *  @param insertImgArr           insertImgArr description
     *  @param appendAttributedString 可为nil
     */
    -(void)configTitleLableAttributedString:(NSArray *)insertImgArr AttributedString:(NSMutableAttributedString *)appendAttributedString{
        if (!insertImgArr || [insertImgArr count] == 0) {
            return ;
        }
        if (!appendAttributedString) {
            appendAttributedString = [[NSMutableAttributedString alloc] initWithString:self.text];
        }
      
        [insertImgArr enumerateObjectsUsingBlock:^(UIImage* img, NSUInteger idx, BOOL * _Nonnull stop) {
            
            NSTextAttachment *textAttachment = [[NSTextAttachment alloc] init];
            //带 x 的
            textAttachment.image = img;
            
            CGFloat mid = self.font.descender + self.font.capHeight;
            CGFloat imgY = self.font.descender - textAttachment.image.size.height/2 + mid + 2;
            textAttachment.bounds = CGRectMake(0, imgY, textAttachment.image.size.width, textAttachment.image.size.height);
            
            NSAttributedString *iconAttributedString = [NSAttributedString attributedStringWithAttachment:textAttachment];
            [appendAttributedString replaceCharactersInRange:NSMakeRange(self.text.length, 0) withAttributedString:iconAttributedString];
            /**
             fix,当文字刚好够一行,添加图片后折行,but.第二行图片和第一行文字没有行间距。。
             http://scottzhu.com/blog/2015/02/14/attach-stars-to-the-end-of-a-uilabel/
             */
            [appendAttributedString appendAttributedString: [[NSAttributedString alloc] initWithString:@" "]];
    
            
        }];
        
        self.attributedText = appendAttributedString;
    }
    
    @end
  • 相关阅读:
    [转]MySQL索引类型
    [转]数据结构(全)
    [转]数据结构基础概念篇
    [转]从零开始搭建创业公司后台技术栈
    将博客搬至CSDN
    编译android源代码(aosp)
    【Android】Fresco图片加载框架(二)————Producer
    【Android】Fresco图片加载框架(一)————源码简要分析
    TSL(SSL)相关内容
    谨慎使用AsyncTask
  • 原文地址:https://www.cnblogs.com/DamonTang/p/5344048.html
Copyright © 2011-2022 走看看