图文混排

目标: 简略实现 文本包含可点击文字和图片

图文混排_第1张图片
富文本

首先自定义一个HZTextAttachment,主要是处理图片,用来保证图片不怎么失真

@interface HZTextAttachment : NSTextAttachment
@end
@implementation HZTextAttachment
- (CGRect)attachmentBoundsForTextContainer:(nullable NSTextContainer *)textContainer proposedLineFragment:(CGRect)lineFrag glyphPosition:(CGPoint)position characterIndex:(NSUInteger)charIndex NS_AVAILABLE(10_11, 7_0) {
    
    //可以在这里修改要展示的图片大小 和位置
    CGFloat attImageWidth = CGRectGetWidth(lineFrag);
    CGFloat attImageHeight = attImageWidth * self.image.size.height/self.image.size.width;
    
    if(self.image.size.width > attImageWidth) {
        UIGraphicsBeginImageContext(CGSizeMake(attImageWidth, attImageHeight));
        [self.image drawInRect:CGRectMake(0, 0, attImageWidth, attImageHeight)];
        self.image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    }
    
   
    
    return CGRectMake(0, 0, self.image.size.width, self.image.size.height);
}
@end

接着拼装一个主体富文本(NSMutableAttributedString)

//创建测试富文本
NSMutableAttributedString *attStr = [[NSMutableAttributedString alloc] initWithString:@"honzon:honzon测试"];
//设置可点击文字内容
[attStr addAttribute:NSLinkAttributeName value:@"honzon" range:NSMakeRange(0,@"honzon".length)];
//设置可点击文字样式
NSDictionary *linkAttributes = @{NSForegroundColorAttributeName: [UIColor blueColor],NSUnderlineColorAttributeName: [UIColor lightGrayColor],NSUnderlineStyleAttributeName: @(NSUnderlinePatternSolid)};

//同步获取图片信息 (请原谅我的懒)
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1497951942874&di=b6c9ca8ea50cfdad624abe35ae7ae4d2&imgtype=0&src=http%3A%2F%2Fpic.58pic.com%2F58pic%2F13%2F87%2F72%2F73t58PICjpT_1024.jpg"]];
  
//自定义TextAttachment 将图片转化为富文本字符
HZTextAttachment *imageAtt = [[HZTextAttachment alloc] init];
imageAtt.image = [UIImage imageWithData:data];
NSAttributedString *imageAttStr = [NSAttributedString attributedStringWithAttachment:imageAtt];
//将富文本拼接在主体富文本上
[attStr appendAttributedString:imageAttStr];

//保存一下主体富文本
self.attStr = attStr;

然后为控制添加一个UITextView,并将主体富文本赋值给该TextView

UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(100, 100, 160, 200)]; 
textView.linkTextAttributes = linkAttributes;
textView.attributedText = attStr;
textView.delegate = self;
textView.editable = NO;

[self.view addSubview:textView];

最后实现代理方法

文字点击方法

#if __IPHONE_10_0
- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange interaction:(UITextItemInteraction)interaction NS_AVAILABLE_IOS(10_0) {
    return [self HZ_textView:textView shouldInteractWithURL:URL inRange:characterRange];
}
#else
- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange {
    return [self HZ_textView:textView shouldInteractWithURL:URL inRange:characterRange];;
}
#endif

- (BOOL)HZ_textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange {
    
    //虽然URL为nil,但是characterRange是有值的,因此一般通过这个characterRange来进行后续操作
    NSString *absoluteString = [self.attStr attributedSubstringFromRange:characterRange].string;
    
    if ([absoluteString isEqualToString:@"honzon"]) {
        NSLog(@"honzon");
    }
    return NO;
}

图片(附件)点击方法

#if __IPHONE_10_0
- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange interaction:(UITextItemInteraction)interaction{
    return [self HZ_textView:textView shouldInteractWithTextAttachment:textAttachment inRange:characterRange];
}
#else
- (BOOL)textView:(UITextView *)textView shouldInteractWithTextAttachment:(NSTextAttachment *)textAttachment inRange:(NSRange)characterRange {
    return [self HZ_textView:textView shouldInteractWithTextAttachment:textAttachment inRange:characterRange];
}
#endif

- (BOOL)HZ_textView:(UITextView *)textView shouldInteractWithTextAttachment:(NSTextAttachment *)textAttachment inRange:(NSRange)characterRange {
    
    UIImage *image = textAttachment.image;
    //可以在这里通过textAttachment取到附件内容
    return NO;
}

你可能感兴趣的:(图文混排)