最近項目中用到了圖文混排,所以就研究了一下iOS中的富文本,打算把研究的結果分享一下,也是對自己學習的一個總結。初步打算寫兩篇,這是第一篇,主要介紹iOS7新出的TextKit的簡單實用。
TextKit是iOS7新推出的文字排版技術,使用TextKit可以很方便的實現富文本、表情混排和圖文混排等效果。TextKit中的幾個關鍵的類:
NSAttributeString和NSMutableAttributeString:屬性字符串和可變屬性字符串,這個TextKit中最基礎的類,文字中的所有富文本屬性都是通過屬性字符串來表現出來的NSTextAttachment:字符串的附件,將圖片,可以將圖片等內容當做一個附件插入到屬性字符串中,可以實現表情混排,鏈接等效果 示例廢話不多說,直接上代碼,先看一下效果圖:

#import "TextKitEmojiTextVC.h"
NSString * str = @"asfasfa阿斯頓發生大發撒放大離開家撒旦法按時付款就阿裡;雙方均asfasdfasfdalkjsflakj阿斯頓發生大發撒旦法asdfasdfaasfdaasa撒旦法;拉斯克獎發了奧斯卡獎罰洛杉矶的法律;看見誰發的阿斯利康就發;了數據庫等法律按實際開發;阿裡就開始放到了;安家費阿裡山科技發達了開始將對方拉開始交電費了卡雙方的空間啊發送卡飛機阿裡開始就放暑假了罰款就是浪費";
@interface TextKitEmojiTextVC ()<UITextViewDelegate>
@property (nonatomic, strong) UITextView * textView;
@end
@implementation TextKitEmojiTextVC
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"普通文字排版&表情混排";
//初始化textView
self.edgesForExtendedLayout = UIRectEdgeNone;
self.textView = [[UITextView alloc] initWithFrame:CGRectMake(20, 20, [UIScreen mainScreen].bounds.size.width - 40, [UIScreen mainScreen].bounds.size.height - 40 - 44 - 20)];
self.textView.backgroundColor = [UIColor cyanColor];
self.textView.text = str;
self.textView.font = [UIFont systemFontOfSize:15];
self.textView.editable = NO;
self.textView.delegate = self;
[self.view addSubview:self.textView];
//設置常規屬性
[self setupNormalAttribute];
//鏈接和表情
[self setupEmojiAndLink];
}
/**
* 向文本中添加表情,鏈接等
*/
- (void)setupEmojiAndLink
{
NSMutableAttributedString * mutStr = [self.textView.attributedText mutableCopy];
//添加表情
UIImage * image1 = [UIImage imageNamed:@"010"];
NSTextAttachment * attachment1 = [[NSTextAttachment alloc] init];
attachment1.bounds = CGRectMake(0, 0, 30, 30);
attachment1.image = image1;
NSAttributedString * attachStr1 = [NSAttributedString attributedStringWithAttachment:attachment1];
[mutStr insertAttributedString:attachStr1 atIndex:50];
//添加表情
UIImage * image2 = [UIImage imageNamed:@"011"];
NSTextAttachment * attachment2 = [[NSTextAttachment alloc] init];
attachment2.bounds = CGRectMake(0, 0, 15, 15);
attachment2.image = image2;
NSAttributedString * attachStr2 = [NSAttributedString attributedStringWithAttachment:attachment2];
[mutStr insertAttributedString:attachStr2 atIndex:100];
//添加鏈接
NSURL * url = [NSURL URLWithString:@"http://www.baidu.com"];
[mutStr addAttribute:NSLinkAttributeName value:url range:NSMakeRange(70, 10)];
self.textView.attributedText = [mutStr copy];
}
/**
* 設置常規屬性
*/
- (void)setupNormalAttribute
{
NSMutableAttributedString * mutStr = [self.textView.attributedText mutableCopy];
//顏色
[mutStr addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(10, 10)];
//字體
[mutStr addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:25] range:NSMakeRange(20, 5)];
//下劃線
[mutStr addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleSingle | NSUnderlinePatternDot) range:NSMakeRange(32, 8)];
//空心字
[mutStr addAttribute:NSStrokeWidthAttributeName value:@(2) range:NSMakeRange(42, 5)];
self.textView.attributedText = [mutStr copy];
}
/**
* 點擊圖片觸發代理事件
*/
- (BOOL)textView:(UITextView *)textView shouldInteractWithTextAttachment:(NSTextAttachment *)textAttachment inRange:(NSRange)characterRange
{
NSLog(@"%@", textAttachment);
return NO;
}
/**
* 點擊鏈接,觸發代理事件
*/
- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange
{
[[UIApplication sharedApplication] openURL:URL];
return YES;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
圖片環繞效果圖:

#import "TextKitImageTextVC.h"
NSString * str1 = @"asfasfa阿斯頓發生大發撒放大離開家撒旦法按時付款就阿裡;雙方均asfasdfasfdalkjsflakj阿斯頓發生大發撒旦法asdfasdfaasfdaasa撒旦法;拉斯克獎發了奧斯卡獎罰洛杉矶的法律;看見誰發的阿斯利康就發;了數據庫等法律按實際開發;阿裡就開始放到了;安家費阿裡山科技發達了開始將對方拉開始交電費了卡雙方的空間啊發送卡飛機阿裡開始就放暑假了罰款就是浪費asfasfa阿斯頓發生大發撒放大離開家撒旦法按時付款就阿裡;雙方均asfasdfasfdalkjsflakj阿斯頓發生大發撒旦法asdfasdfaasfdaasa撒旦法;拉斯克獎發了奧斯卡獎罰洛杉矶的法律;看見誰發的阿斯利康就發;了數據庫等法律按實際開發;阿裡就開始放到了;安家費阿裡山科技發達了開始將對方拉開始交電費了卡雙方的空間啊發送卡飛機阿裡開始就放暑假了罰款就是浪費asfasfa阿斯頓發生大發撒放大離開家撒旦法按時付款就阿裡;雙方均asfasdfasfdalkjsflakj阿斯頓發生大發撒旦法asdfasdfaasfdaasa撒旦法;拉斯克獎發了奧斯卡獎罰洛杉矶的法律;看見誰發的阿斯利康就發;了數據庫等法律按實際開發;阿裡就開始放到了;安家費阿裡山科技發達了開始將對方拉開始交電費了卡雙方的空間啊發送卡飛機阿裡開始就放暑假了罰款就是浪費";
@interface TextKitImageTextVC ()
@property (nonatomic, strong) UITextView * textView;
@end
@implementation TextKitImageTextVC
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.title = @"文字環繞";
//初始化textLabel
self.edgesForExtendedLayout = UIRectEdgeNone;
self.textView = [[UITextView alloc] initWithFrame:CGRectMake(20, 20, [UIScreen mainScreen].bounds.size.width - 40, [UIScreen mainScreen].bounds.size.height - 40 - 44 - 20)];
self.textView.backgroundColor = [UIColor cyanColor];
self.textView.text = str1;
self.textView.font = [UIFont systemFontOfSize:15];
self.textView.editable = NO;
[self.view addSubview:self.textView];
//圖文混排,設置圖片的位置
UIImageView * imageView = [[UIImageView alloc] initWithFrame:CGRectMake(120, 120, 100, 110)];
imageView.image = [UIImage imageNamed:@"011"];
imageView.backgroundColor = [UIColor redColor];
[self.view addSubview:imageView];
CGRect rect = CGRectMake(100, 100, 100, 100);
//設置環繞的路徑
UIBezierPath * path = [UIBezierPath bezierPathWithRect:rect];
self.textView.textContainer.exclusionPaths = @[path];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
總結TextKit極大的簡化了文字排版的復雜度,但是它的缺點也很明顯,就是只能在iOS7之後的系統中使用,很多需要兼容iOS7以前的系統的應用都沒法使用。不過隨著技術的發展,相信它的應用也會越來越廣泛。