ios零碎记录OtheriOS专题资源__UI专题

UILabel封装——生成富文本,计算文本高度,图文混排

2016-03-14  本文已影响2641人  Wang66

更新

(2016.08.09)在最近的项目开发中碰到了像下图这样文本中混合图标的情况,如果分为UILabel和UIImageView两个控件来写,本身就比较繁琐,而且要考虑若文本较长时图标是要换行显示,即UIImageView要更新布局。今天有时间,利用TextKitNSTextAttachment将图片作为富文本的附件植入富文本,并且写了一个UILable的分类进行了封装。当然也完全可以不写成分类的形式,直接封装入YWLabel也是可以的。

屏幕快照 2016-08-09 下午5.36.06.png

YWLabel

项目中富文本的展示非常普遍,若通过UILable的接口方法去设置是非常繁琐麻烦的,另外,文本动态高度计算的问题也很常见,因此有必要对UILabel进行封装。以便我们处理这两个问题,下面这个YWLabel主要就针对这两个问题进行了封装,给开发提供方便,提高效率。


// YWLabel.h

#import <UIKit/UIKit.h>

@interface YWLabel : UILabel


- (void)labelText:(NSString *)text
      lineSpacing:(CGFloat)l_spacing;


- (void)labelText:(NSString *)text
   sectionSpacing:(CGFloat)s_spacing
      lineSpacing:(CGFloat)l_spacing;


+ (NSAttributedString *)attributedTextArray:(NSArray *)texts
                                 textColors:(NSArray *)colors
                                 textfonts:(NSArray *)fonts;


+ (NSAttributedString *)attributedTextArray:(NSArray *)texts
                                 textColors:(NSArray *)colors
                                 textfonts:(NSArray *)fonts
                                lineSpacing:(CGFloat)l_spacing;


+ (CGSize)sizeLabelWidth:(CGFloat)width
          attributedText:(NSAttributedString *)attributted;


+ (CGSize)sizeLabelWidth:(CGFloat)width
                    text:(NSString *)text
                    font:(UIFont *)font;


+ (CGSize)sizeLabelWidth:(CGFloat)width
                    text:(NSString *)text
                    font:(UIFont *)font
             lineSpacing:(CGFloat)l_spacing;

@end
// YWLabel.m

#import "YWLabel.h"

@implementation YWLabel


- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if(self)
    {
        self.backgroundColor = [UIColor whiteColor];
    }
    
    return self;
}


- (void)labelText:(NSString *)text
      lineSpacing:(CGFloat)l_spacing
{
    if(l_spacing<0){
        self.text = text;
        return;
    }
    self.numberOfLines = 0;
    
    NSMutableAttributedString *attributedStr = [[NSMutableAttributedString alloc] initWithString:text];
    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
    paragraphStyle.lineSpacing = l_spacing;
    
    [attributedStr addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, text.length)];
    [attributedStr addAttribute:NSForegroundColorAttributeName value:self.textColor range:NSMakeRange(0, text.length)];
    [attributedStr addAttribute:NSFontAttributeName value:self.font range:NSMakeRange(0, text.length)];
    
    self.attributedText = attributedStr;
}



- (void)labelText:(NSString *)text
   sectionSpacing:(CGFloat)s_spacing
      lineSpacing:(CGFloat)l_spacing
{
    if(s_spacing<=0 && l_spacing<=0){
        self.text = text;
        return;
    }
    
    self.numberOfLines = 0;
    
    NSMutableAttributedString *attributedStr = [[NSMutableAttributedString alloc] initWithString:text];
    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
    paragraphStyle.lineSpacing = l_spacing; // lineSpacing
    paragraphStyle.paragraphSpacing = s_spacing; // paragraphSpacing
    [attributedStr addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, text.length)];
    [attributedStr addAttribute:NSForegroundColorAttributeName value:self.textColor range:NSMakeRange(0, text.length)];
    [attributedStr addAttribute:NSFontAttributeName value:self.font range:NSMakeRange(0, text.length)];
    
    self.attributedText = attributedStr;
}


+ (NSAttributedString *)attributedTextArray:(NSArray *)texts
                                 textColors:(NSArray *)colors
                                  textfonts:(NSArray *)fonts
{
    if(texts.count == 0){
        return nil;
    }
    
    NSMutableAttributedString *resultAttributedStr = [[NSMutableAttributedString alloc] init];
    for(int i=0; i<texts.count; i++)
    {
        NSString *text = texts[i];
        NSMutableAttributedString *mAttributedStr = [[NSMutableAttributedString alloc] initWithString:text];
        [mAttributedStr addAttribute:NSForegroundColorAttributeName value:colors[i] range:NSMakeRange(0, text.length)];
        [mAttributedStr addAttribute:NSFontAttributeName value:fonts[i] range:NSMakeRange(0, text.length)];
        [resultAttributedStr appendAttributedString:mAttributedStr];
    }
    
    return resultAttributedStr;
    
}


+ (NSAttributedString *)attributedTextArray:(NSArray *)texts
                                 textColors:(NSArray *)colors
                                  textfonts:(NSArray *)fonts
                                lineSpacing:(CGFloat)l_spacing
{
    if(texts.count == 0){
        return nil;
    }
        
    NSMutableAttributedString *resultAttributedStr = [[NSMutableAttributedString alloc] init];
    
    for(int i=0; i<texts.count; i++)
    {
        NSString *text = texts[i];
        NSMutableAttributedString *mAttributedStr = [[NSMutableAttributedString alloc] initWithString:text];
        [mAttributedStr addAttribute:NSForegroundColorAttributeName value:colors[i] range:NSMakeRange(0, text.length)];
        [mAttributedStr addAttribute:NSFontAttributeName value:fonts[i] range:NSMakeRange(0, text.length)];
        [resultAttributedStr appendAttributedString:mAttributedStr];
    }
    
    if(l_spacing>0){
        NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
        paragraphStyle.lineSpacing = l_spacing;
        [resultAttributedStr addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, resultAttributedStr.length)];
    }

    
    return resultAttributedStr;
}



+ (CGSize)sizeLabelWidth:(CGFloat)width
          attributedText:(NSAttributedString *)attributted
{
    if(width<=0){
        return CGSizeZero;
    }
    
    UILabel *lab = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, width, 1000)];
    lab.attributedText = attributted;
    lab.numberOfLines = 0;
    
    CGSize labSize = [lab sizeThatFits:lab.bounds.size];
    return labSize;
}


+ (CGSize)sizeLabelWidth:(CGFloat)width
                    text:(NSString *)text
                    font:(UIFont *)font
{
    if(width<=0 || text.length == 0){
        return CGSizeZero;
    }
    
    UILabel *lab = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, width, 1000)];
    lab.text = text;
    if(font){
        lab.font = font;
    }
    
    CGSize labSize = [lab sizeThatFits:lab.bounds.size];
    return labSize;
}


+ (CGSize)sizeLabelWidth:(CGFloat)width
                    text:(NSString *)text
                    font:(UIFont *)font
             lineSpacing:(CGFloat)l_spacing
{
    if(width<=0 || text.length == 0){
        return CGSizeZero;
    }
    
    if(l_spacing<=0){
        UILabel *lab = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, width, 1000)];
        lab.text = text;
        lab.numberOfLines = 0;
        if(font){
            lab.font = font;
        }
        
        CGSize labSize = [lab sizeThatFits:lab.bounds.size];
        return labSize;
    }
    else
    {
        UILabel *lab = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, width, 1000)];
        lab.numberOfLines = 0;
        if(font){
            lab.font = font;
        }
        NSMutableAttributedString *mAttriStr = [[NSMutableAttributedString alloc] initWithString:text];
        NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
        paragraphStyle.lineSpacing = l_spacing;
        [mAttriStr addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, text.length)];
        lab.attributedText = mAttriStr;
        
        CGSize labSize = [lab sizeThatFits:lab.bounds.size];
        return labSize;
    }
}

@end

上面就是我们封装的YWLabel,下面我们来测试一下:

// ViewController.m

#import "ViewController.h"
#import "YWLabel.h"


#define Lab_W self.view.bounds.size.width-30.f
#define FONT(X) [UIFont systemFontOfSize:X]
#define BFONT(X) [UIFont boldSystemFontOfSize:X]
@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.view.backgroundColor = [UIColor lightGrayColor];
    
    NSArray *textsArray = @[@"你呀别总想搞个大新闻!",
                            @"图样图森破!",
                            @"什么大风大浪我没见过",
                            @"我和华莱士谈笑风生"];
    
    NSArray *colorsArray = @[[UIColor orangeColor],
                             [UIColor redColor],
                             [UIColor blueColor],
                             [UIColor greenColor]];
    
    NSArray *fontsArray = @[FONT(20), BFONT(35), FONT(25), BFONT(30)];
    
    YWLabel *lab = [[YWLabel alloc] initWithFrame:CGRectMake(15.f, 80.f, Lab_W, 10)];
    lab.numberOfLines = 0;
    // 生成富文本字符串
    NSAttributedString *attributeStr = [YWLabel attributedTextArray:textsArray
                                                         textColors:colorsArray
                                                          textfonts:fontsArray
                                                        lineSpacing:20.f];
    lab.attributedText = attributeStr;
    // 计算富文本的高度
    CGFloat lab_h = [YWLabel sizeLabelWidth:Lab_W
                             attributedText:attributeStr].height;
    lab.frame = CGRectMake(15.f, 80.f, Lab_W, lab_h);
    
    [self.view addSubview:lab];
}

@end

效果图:

屏幕快照 2016-03-14 20.44.44.png

UILabel+ImageTextFix

——UILabel+ImageTextFix.h——

#import <UIKit/UIKit.h>

@interface UILabel (ImageTextFix)

// 由多个attributedString拼接成新的attributedString,item意为由text或image生成的单个attributedString
+ (NSAttributedString *)fixAttributeStrWithItems:(NSArray *)items;


// 
+ (NSAttributedString *)fixAttributedStrWithTexts:(NSArray *)texts
                                textColors:(NSArray *)colors
                                 textfonts:(NSArray *)fonts
                                     image:(UIImage *)image
                               insertIndex:(NSInteger)index
                               lineSpacing:(CGFloat)l_spacing;



+ (NSAttributedString *)fixAttributedStrWithTexts:(NSArray *)texts
                                       textColors:(NSArray *)colors
                                        textfonts:(NSArray *)fonts
                                            image:(UIImage *)image
                                      insertIndex:(NSInteger)index
                                      imageBounds:(CGRect)bounds
                                      lineSpacing:(CGFloat)l_spacing;


// 由text生成attributedString
+ (NSAttributedString *)attributedStrWithText:(NSString *)text textColor:(UIColor *)color textFont:(UIFont *)font;


// 由image生成attributedString
+ (NSAttributedString *)attributedStrWithImage:(UIImage *)image imageBounds:(CGRect)bounds;


@end

——UILabel+ImageTextFix.m——

#import "UILabel+ImageTextFix.h"



@implementation UILabel (ImageTextFix)

// 由多个attributedString拼接成新的attributedString,item意为由text或image生成的单个attributedString
+ (NSAttributedString *)fixAttributeStrWithItems:(NSArray *)items
{
    NSMutableAttributedString *resultMAttrStr = [[NSMutableAttributedString alloc] init];
    for(int i=0; i<items.count; i++)
    {
        if([items[i] isKindOfClass:[NSAttributedString class]]){
            [resultMAttrStr appendAttributedString:items[i]];
        }
    }
    
    return resultMAttrStr;
}



// 图文混合,只有一张图片
+ (NSAttributedString *)fixAttributedStrWithTexts:(NSArray *)texts
                                       textColors:(NSArray *)colors
                                        textfonts:(NSArray *)fonts
                                            image:(UIImage *)image
                                      insertIndex:(NSInteger)index
                                      lineSpacing:(CGFloat)l_spacing
{
    return [[self class] fixAttributedStrWithTexts:texts
                                        textColors:colors
                                         textfonts:fonts
                                             image:image
                                       insertIndex:index
                                       imageBounds:CGRectZero
                                       lineSpacing:l_spacing];
}


// 同上,多了一个l_spacing参数
+ (NSAttributedString *)fixAttributedStrWithTexts:(NSArray *)texts
                                       textColors:(NSArray *)colors
                                        textfonts:(NSArray *)fonts
                                            image:(UIImage *)image
                                      insertIndex:(NSInteger)index
                                      imageBounds:(CGRect)bounds
                                      lineSpacing:(CGFloat)l_spacing

{
    if(texts.count==0){
        return nil;
    }
    
    NSMutableAttributedString *resultAttrStr = [[NSMutableAttributedString alloc] init];
    NSInteger locationIndex = 0;
    for(int i=0; i<texts.count; i++)
    {
        NSString *text = texts[i];
        NSAttributedString *tempMAttrStr = [[self class] attributedStrWithText:texts[i] textColor:colors[i] textFont:fonts[i]];
        [resultAttrStr appendAttributedString:tempMAttrStr];
        
        // 计算图片应该插入的位置
        if(index<=texts.count){
            if(index == 0){
                locationIndex = 0;
            }
            else{
                if(i<index){
                    locationIndex+=text.length;
                }
            }
        }
        
    }
    if(l_spacing>0){
        NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
        paragraphStyle.lineSpacing = l_spacing;
        [resultAttrStr addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, resultAttrStr.length)];
    }
    
    // 插入图片附件(插入图片要在最后,不然会有影响)
    NSMutableAttributedString *resultAttrStr1 = [[self class] insertMAttrStr:resultAttrStr image:image imageBounds:bounds insertIndex:locationIndex];
    
    
    return resultAttrStr1;
}



+ (NSMutableAttributedString *)insertMAttrStr:(NSMutableAttributedString *)mAttrStr image:(UIImage *)image imageBounds:(CGRect)bounds insertIndex:(NSInteger)index
{
    if(image){
        NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
        attachment.image = image;
        attachment.bounds = CGRectMake(bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height);
        NSAttributedString *attachmentAttrStr = [NSAttributedString attributedStringWithAttachment:attachment];
        [mAttrStr insertAttributedString:attachmentAttrStr atIndex:index];
    }
    
    return [mAttrStr copy];
}




// 由text生成attributedString
+ (NSAttributedString *)attributedStrWithText:(NSString *)text textColor:(UIColor *)color textFont:(UIFont *)font
{
    NSMutableAttributedString *mAttrStr = [[NSMutableAttributedString alloc] initWithString:text];
    [mAttrStr addAttribute:NSForegroundColorAttributeName value:color range:NSMakeRange(0, text.length)];
    [mAttrStr addAttribute:NSFontAttributeName value:font range:NSMakeRange(0, text.length)];
    
    return mAttrStr;
}

// 由image生成attributedString
+ (NSAttributedString *)attributedStrWithImage:(UIImage *)image imageBounds:(CGRect)bounds
{
    NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
    attachment.image = image;
    attachment.bounds = CGRectMake(bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height);
    NSAttributedString *attachmentAttrStr = [NSAttributedString attributedStringWithAttachment:attachment];
    
    return attachmentAttrStr;
}

@end

——使用——

方式1:

    // 数据初始化
    UIImage *icon = [UIImage imageNamed:@"biaoji-dacuxiao"];
    NSArray *texts = @[@"大起飞精品钢琴课程 ",@"买买买!!!",@"1200元 "];
    NSArray *colors = @[[UIColor lightGrayColor],[UIColor orangeColor],[UIColor redColor]];
    NSArray *fonts = @[[UIFont systemFontOfSize:15],[UIFont systemFontOfSize:15],[UIFont systemFontOfSize:25]];
    
    UILabel *lab = [[UILabel alloc] initWithFrame:CGRectMake(15.f, 550.f, self.view.bounds.size.width-30.f, 80.f)];
    [self.view addSubview:lab];
    lab.numberOfLines = 0;
    // ----1----图文混合,只有一张图片
    lab.attributedText = [UILabel fixAttributedStrWithTexts:texts
                                                 textColors:colors
                                                  textfonts:fonts
                                                      image:icon
                                                   insertIndex:3
                                                   imageBounds:CGRectMake(0, 5.f, icon.size.width, icon.size.height)
                                                   lineSpacing:5.f];
style1.png

方式2:

    UILabel *lab = [[UILabel alloc] initWithFrame:CGRectMake(15.f, 550.f, self.view.bounds.size.width-30.f, 80.f)];
    [self.view addSubview:lab];
    lab.numberOfLines = 0;

    // ----2----由多个attributedString拼接成新的attributedString
    NSAttributedString *attrStr1 = [UILabel attributedStrWithText:@"大中华精品钢琴课程 " textColor:[UIColor lightGrayColor] textFont:[UIFont systemFontOfSize:15]];
    NSAttributedString *attrStr2 = [UILabel attributedStrWithImage:icon imageBounds:CGRectMake(0, 5.f, icon.size.width, icon.size.height)];
    NSAttributedString *attrStr3 = [UILabel attributedStrWithText:@"1200元 " textColor:[UIColor redColor] textFont:[UIFont systemFontOfSize:25]];
    NSAttributedString *attrStr4 = [UILabel attributedStrWithText:@"买买买" textColor:[UIColor orangeColor] textFont:[UIFont systemFontOfSize:15]];
    NSAttributedString *attrStr5 = [UILabel attributedStrWithImage:icon imageBounds:CGRectMake(0, -15.f, icon.size.width, icon.size.height)];
    NSAttributedString *resultAttrStr = [UILabel fixAttributeStrWithItems:@[attrStr1,attrStr2,attrStr3,attrStr4,attrStr5]];
    lab.attributedText = resultAttrStr;
style2.png

注:NSTextAttachmentbounds属性,应该是用于指定图片附件的位置及尺寸的,但是图片的x坐标指定试了好多次始终是无效的。若文本和图片之间需要间距,上面代码目前是通过空格的本办法实现的。如果有朋友知道怎么指定图片附件的位置,可以告诉我,谢谢。

上一篇下一篇

猜你喜欢

热点阅读