關於圖文混排,其實之前的博客已經討論不少,在實際開發中,常常使用第三方的框架來完成排版的需求,其中RCLabel和RTLabel是兩個比較好用的第三方庫,他們的實現都是基於UIView的,經過更底層的CoreText相關API來進行圖文處理。相關介紹博客地址以下:數組
iOS中支持HTML標籤渲染的MDHTMLLaebl:http://my.oschina.net/u/2340880/blog/703254。網絡
擴展於RCLabel的支持異步加載網絡圖片的富文本引擎的設計:http://my.oschina.net/u/2340880/blog/499311。app
iOS開發封裝一個能夠響應超連接的label——基於RCLabel的交互擴展:http://my.oschina.net/u/2340880/blog/550194。框架
CoreText是一個比較底層且十分強大的文本渲染框架,可是其使用起來並非十分方便。在較低版本的iOS系統中,要進行富文本排版十分困難。在iOS6中,系統爲UILabel,UITextView等這類文本渲染控件引入了NSAttributedString屬性,有了NSAttributedString這個類,建立靈活多彩的文本控件變得十分輕鬆,開發者只須要配置NSAttributedString屬性字符串便可。可是要進行圖文混排,依然比較困難。iOS7以後引入TextKit框架,就完美的解決了圖文混排這樣的問題。異步
首先,iOS7中新添加了一類NSTextAttachment,從類名理解它是一個文本附件,其實也正是如此,NSTextAttachment類能夠向文本中添加一些附件,這有些向郵件系統,寄信者能夠向郵件中添加附件一同發送出去。NSTextAttachment類並不直接參與富文本的渲染與佈局,渲染和佈局依然由NSAttributedString類來完成,NSAttributedString類中提供了方法將NSTextAttachment所描述的內容轉換爲NSAttributedString示例。以一個簡單的圖文混排爲例:佈局
- (void)viewDidLoad { [super viewDidLoad]; //進行NSTextAttachment的建立 NSTextAttachment * attach = [[NSTextAttachment alloc]init]; //設置顯示的圖片 attach.image =[UIImage imageNamed:@"image"]; //設置尺寸 attach.bounds = CGRectMake(0, 0, 120, 60); NSTextAttachment * attach2 = [[NSTextAttachment alloc]init]; attach2.image =[UIImage imageNamed:@"image2"]; attach2.bounds = CGRectMake(0, 0, 100, 90); //建立文本NSAttributedString對象 NSMutableAttributedString * attri = [[NSMutableAttributedString alloc]initWithString:@"Describes a dictionary that fully specifies a font.... UIFontDescriptorInherits From NSObject UIFontDescriptor NSObject UIFontDescriptor Conforms To CVarArgT... 這裏是中文"]; //將NSTextAttachment映射爲NSAttributedString對象 NSMutableAttributedString * att = [[NSMutableAttributedString alloc]initWithAttributedString:[NSAttributedString attributedStringWithAttachment:attach]]; //將圖片插入NSAttributedString中 [attri insertAttributedString:att atIndex:15]; [attri insertAttributedString:[NSAttributedString attributedStringWithAttachment:attach2] atIndex:130]; UILabel * label = [[UILabel alloc]initWithFrame:CGRectMake(20, 20, 280, 540)]; label.backgroundColor = [UIColor grayColor]; label.numberOfLines = 0; label.attributedText = attri; [self.view addSubview:label]; }
運行工程後,效果以下圖所示,其實只使用UILabel也能夠實現複雜的富文本和圖文混排:url
TextKit框架強大到只使用UILabel就能夠完成複雜的富文本佈局,可是UILabel有一個致命的缺陷,其沒法進行用戶交互。試想,若是能夠向一段文本中添加任意數據類型的文件,當用戶點擊這個文件時,能夠獲取到文件數據並進行業務邏輯處理,這將十分酷。這樣富文本佈局其實就不僅侷限於圖文混排了,咱們能夠插入音頻,插入視頻,甚至插入任意自定義格式的數據。結合使用NSTextAttachment與UITextView,這些都能實現。先看NSTextAttachment類中的一些經常使用屬性與方法:spa
//這個初始化方法用於建立攜帶任意數據的文本附件 - (instancetype)initWithData:(nullable NSData *)contentData ofType:(nullable NSString *)uti NS_DESIGNATED_INITIALIZER NS_AVAILABLE(10_11, 7_0); //攜帶的數據內容 @property(nullable, copy, NS_NONATOMIC_IOSONLY) NSData *contents NS_AVAILABLE(10_11, 7_0); //數據類型 @property(nullable, copy, NS_NONATOMIC_IOSONLY) NSString *fileType NS_AVAILABLE(10_11, 7_0); //設置渲染的圖片 須要注意 若是設置的這個 附件攜帶的數據 fileWrapper目錄內容將無效 @property(nullable, strong, NS_NONATOMIC_IOSONLY) UIImage *image NS_AVAILABLE(10_11, 7_0); //設置圖片渲染的尺寸 @property(NS_NONATOMIC_IOSONLY) CGRect bounds NS_AVAILABLE(10_11, 7_0); //設置附件攜帶的文件目錄 須要注意 若是設置了這個屬性 image和data將無效 @property(nullable, strong, NS_NONATOMIC_IOSONLY) NSFileWrapper *fileWrapper;
結合UITextView能夠爲NSAttributedString屬性字符串添加超連接,在代碼回調中監聽此超連接的回調能夠獲取NSTextAttachment攜帶的附件內容,如此就能夠自由的進行業務處理了,示例代碼以下:.net
- (void)viewDidLoad { [super viewDidLoad]; //保留一個數組存放附件 _attArray = [NSMutableArray array]; //建立附件數據 NSData * stringData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"image3" ofType:@"gif"]]; NSTextAttachment * attach = [[NSTextAttachment alloc]initWithData:stringData ofType:@"gif"]; [_attArray addObject:attach]; attach.bounds = CGRectMake(0, 0, 30, 40); NSMutableAttributedString * attri = [[NSMutableAttributedString alloc]initWithString:@"Describes a dictionary that fully specifies a font.... UIFontDescriptorInherits From NSObject UIFontDescriptor NSObject UIFontDescriptor Conforms To CVarArgT... 這裏是中文"]; NSMutableAttributedString * att = [[NSMutableAttributedString alloc]initWithAttributedString:[NSAttributedString attributedStringWithAttachment:attach]]; //爲NSTextAttachment轉換爲的NSAttributedString添加超連接 [att addAttributes:@{NSLinkAttributeName:@"url..."} range:NSMakeRange(0, att.string.length)]; [attri insertAttributedString:att atIndex:15]; UITextView * textView = [[UITextView alloc]initWithFrame:CGRectMake(20, 20, 280, 540)]; textView.backgroundColor = [UIColor grayColor]; textView.dataDetectorTypes = UIDataDetectorTypeLink; textView.delegate =self; textView.attributedText = attri; textView.editable = NO; [self.view addSubview:textView]; }
實現以下的TextView代理方法:設計
-(BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange{ //能夠獲取到url 進行匹配 NSLog(@"%@",URL); //取出NSTextAttachment附件 NSTextAttachment * attach =_attArray.firstObject; NSLog(@"%@--",attach.contents); return YES; }
向文本中添加任意數據的NSTextAttachment會展示一個文件的圖標,以下圖所示:
當用戶點擊文件圖標時,會將攜帶的gif文件數據進行打印。
專一技術,熱愛生活,交流技術,也作朋友。
——琿少 QQ羣:203317592