天天看点

利用TextKit进行简单的图文混排

最近做的项目属论坛性质,其中大范围的涉及到图文混排,帖子标题前有图片,像“顶”“荐”赏“精”图片,如图:

利用TextKit进行简单的图文混排

由此,自已封装了一个工具类,仅做参考:

1,首先上一份完整的代码,业务需求是根据后台返回的标识显示图片,其中参数topic存放所需标识和标题,参数isShow是因为悬赏帖有的地方会单独在界面有个标识,无需在标题前显示,标识分别如下:

// topic.topiclevel 置顶, topic.topicrecommend 推荐, topic.topicessence 精华, topic.topictype == 2 悬赏
           
//
//  LTIntegrateTextAndGraphics.m
//
//  Created by MaLingYun on 16/3/4.
//

#import "LTIntegrateTextAndGraphics.h"
#import "XMTextAttachment.h"

// 在话题前插入“顶、精、推、赏”图片的位置
static int typeIndex;

@implementation LTIntegrateTextAndGraphics
// 调该方法实现图文混排
+ (NSMutableAttributedString *)integrateTextAndGraphicsWithTopic:(BPTopic *)topic withRewardIconIsShow:(BOOL)isShow{
    if (topic.topiclevel || topic.topicrecommend || topic.topicessence || topic.topictype == 2) {
        
        // topic.topictitle 是帖子标题,原始数据
        NSMutableAttributedString *originalString = [[NSMutableAttributedString alloc] initWithString:topic.topictitle attributes:nil];
        // 添加空格是为了插入图片
        NSString *str = [@"   " stringByAppendingString:topic.topictitle];
        NSMutableAttributedString *mString = [[NSMutableAttributedString alloc] initWithString:str attributes:nil];
        
        return [self insertImageInTitleWithString:originalString  withMutableAttributedString:mString withTopic:topic withRewardIconIsShow:isShow];
    }else{
        // 若无任何标识,即普通帖
        NSMutableAttributedString *mString = [[NSMutableAttributedString alloc] initWithString:topic.topictitle attributes:nil];
        return mString;
    }
    
}
+ (NSMutableAttributedString *)insertImageInTitleWithString:(NSMutableAttributedString *)originalString withMutableAttributedString:(NSMutableAttributedString *)mString withTopic:(BPTopic *)topic withRewardIconIsShow:(BOOL)isShow{
    typeIndex = 0;
    NSMutableAttributedString *string = originalString;
    if (topic.topiclevel) {
        string = [self attachmentWithImageName:@"topic_level" withIndex:typeIndex  withMutableAttributedString:mString];
    }
    if (topic.topicrecommend) {
        string = [self attachmentWithImageName:@"topic_recommend" withIndex:typeIndex  withMutableAttributedString:mString];
    }
    if (topic.topicessence) {
        string = [self attachmentWithImageName:@"topic_essence" withIndex:typeIndex  withMutableAttributedString:mString];
    }
    if (topic.topictype == 2) {
        if (isShow) {
            string = [self attachmentWithImageName:@"it_small_reward" withIndex:typeIndex  withMutableAttributedString:mString];
        }
    }
    
    if (topic.topiclevel || topic.topicrecommend || topic.topicessence || isShow) {
        return string;
    } else {// 帖子只为悬赏帖且不显示悬赏标识 则 只返回原始数据
        return originalString;
    }
}
// 核心方法,添加图片
+ (NSMutableAttributedString *)attachmentWithImageName:(NSString *)imgName withIndex:(int)i withMutableAttributedString:(NSMutableAttributedString *)mString{
    XMTextAttachment *attch = [[XMTextAttachment alloc] initWithData:nil ofType:nil];
    attch.image = [LTUtils LTImageNamed:imgName];
    
    NSAttributedString *string = [NSAttributedString attributedStringWithAttachment:attch];
    // 插入的位置为2的倍数,这样图片不至于挨在一起
    [mString insertAttributedString:string atIndex:2 * i];
    typeIndex  += 1;
    return mString;
}
@end

           

在核心方法中,我一开始并没有重写NSTextAttachment,而是直接设置图片的Frame,数值是大概猜一下然后一点一点调整的,代码如下:

attch.bounds = CGRectMake(0, -2, 15, 15);
           

对,没错,你们说的对,这样写是不专业的表现......

图文混排嘛,顾名思义图片与文字在一行,那么图片的高度如何随字体大小(行的高度)改变而二者保持一致?

我重写了NSTextAttachment,在里面:

//
//  XMTextAttachment.m
//
//  Created by malingyun on 16/3/4.
//

#import "XMTextAttachment.h"

@implementation XMTextAttachment

- (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)textContainer proposedLineFragment:(CGRect)lineFrag glyphPosition:(CGPoint)position characterIndex:(NSUInteger)charIndex {
    // y值之所以是-2,是因为若为0,图片的位置比之文字会偏上
    return CGRectMake(0, -2, lineFrag.size.height, lineFrag.size.height);
}

@end
           

图文混排,我现在就接触到这里,以后有深层次的研究再更新。

至此,小马述一家之言。