YYText

1.里面主要兩個控件:

YYTextView 和 YYLabel

現(xiàn)在主要是YYTextview的簡單使用

YYText主要是NSMutableAttributedString來處理富文本 他的內(nèi)部實(shí)現(xiàn)可以自己去深究欲虚。

簡單的圖文并排能岩,使用NSMutableAttributedString創(chuàng)建一個對象 然后 appendAttributesString來拼接文字和圖片(占位)//

//??TextAndImageTextViewVC.h

//??YYTextDemo

//

//??Created?by?linpeng?on?16/3/13.

//??Copyright???2016年?ibireme.?All?rights?reserved.

//

#import

@interface?TextAndImageTextViewVC?:?UIViewController

@end

//

//??TextAndImageTextViewVC.m

//??YYTextDemo

//

//??Created?by?linpeng?on?16/3/13.

//??Copyright???2016年?ibireme.?All?rights?reserved.

//

#import?"TextAndImageTextViewVC.h"

#import?"YYText.h"

#import?"UIView+YYAdd.h"

#import?"YYTextView.h"

#import?"YYImage.h"

#import?"NSBundle+YYAdd.h"

#import?"NSString+YYAdd.h"

@interface?TextAndImageTextViewVC?()

@end

YYTextView?*textView;

@implementation?TextAndImageTextViewVC

-?(void)viewDidLoad?{

[super?viewDidLoad];

[self.view?setBackgroundColor:[UIColor?whiteColor]];

textView=?[[YYTextView?alloc]?initWithFrame:CGRectMake(0,?0,?0,?0)];

textView.userInteractionEnabled=YES;

textView.textVerticalAlignment=YYTextVerticalAlignmentTop;

textView.size=CGSizeMake(self.view.frame.size.width,?self.view.frame.size.height);

//創(chuàng)建最主要的attribute文本

NSMutableAttributedString?*contentText=?[NSMutableAttributedString?new];

UIFont?*font=?[UIFont?systemFontOfSize:16];

//圖片資源

YYImage?*image=?[YYImage?imageNamed:@"demo.jpg"];

image.preloadAllAnimatedImageFrames=YES;

//添加文本+圖片

[contentText?appendAttributedString:[[NSAttributedString?alloc]?initWithString:@"這是第一站圖片"?attributes:nil]];

{

YYAnimatedImageView?*imageView=?[[YYAnimatedImageView?alloc]?initWithImage:image];

imageView.frame=CGRectMake(0,?0,?textView.width?-?10,?textView.width/image.size.width*image.size.height);

NSMutableAttributedString?*attachText=?[NSMutableAttributedString?yy_attachmentStringWithContent:imageView?contentMode:UIViewContentModeScaleAspectFit?attachmentSize:imageView.size?alignToFont:font?alignment:YYTextVerticalAlignmentCenter];

[contentText?appendAttributedString:attachText];

}

//添加文本+圖片

[contentText?appendAttributedString:[[NSAttributedString?alloc]?initWithString:@"\n?接下來是第二張"?attributes:nil]];

{

YYAnimatedImageView?*imageView2=?[[YYAnimatedImageView?alloc]?initWithImage:image];

imageView2.frame=CGRectMake(0,?0,?textView.width?-?10,?textView.width/image.size.width*image.size.height);

NSMutableAttributedString?*attachText2=?[NSMutableAttributedString?yy_attachmentStringWithContent:imageView2?contentMode:UIViewContentModeScaleAspectFit?attachmentSize:imageView2.size?alignToFont:font?alignment:YYTextVerticalAlignmentCenter];

[contentText?appendAttributedString:attachText2];

}

textView.attributedText=contentText;

[self.view?addSubview:textView];

//獲取圖片資源

NSArray?*attachments=textView.textLayout.attachments;

for(YYTextAttachment?*attachment?in?attachments)

{

YYAnimatedImageView?*imageView=attachment.content;

YYImage?*image=?(YYImage?*)imageView.image;

NSLog(@"獲取到圖片:%@",image);

}

NSArray?*attachmentRanges=textView.textLayout.attachmentRanges;

for?(NSValue?*range?in?attachmentRanges)

{

NSRanger=?[range?rangeValue];

NSLog(@"資源所在位置:%ld?長度:?%ld",r.location,r.length);

}

}

-?(void)didReceiveMemoryWarning?{

[super?didReceiveMemoryWarning];

//?Dispose?of?any?resources?that?can?be?recreated.

}

/*

#pragma?mark?-?Navigation

//?In?a?storyboard-based?application,?you?will?often?want?to?do?a?little?preparation?before?navigation

-?(void)prepareForSegue:(UIStoryboardSegue?*)segue?sender:(id)sender?{

//?Get?the?new?view?controller?using?[segue?destinationViewController].

//?Pass?the?selected?object?to?the?new?view?controller.

}

*/

@end

以上代碼加上注釋應(yīng)該很容易理解就不多講了? 注意 \n 這個換行符的使用

看效果圖:

(可編輯的文本+圖片 有的app需要編輯文章功能 用這個就個可以大體實(shí)現(xiàn)了赛蔫,圖片和文本都已經(jīng)獲取到了 到時后對應(yīng)傳到服務(wù)器,之前沒用YYTextview也實(shí)現(xiàn)過這種功能摊沉,效果比較差矗钟,用這個實(shí)現(xiàn)恳蹲,相當(dāng)完美,必須給YYText作者點(diǎn)個贊)

上一篇博客記錄了一個圖文編輯器的功能(YYTextview的使用)响禽,接下來記錄一下YYLabel的簡單使用徒爹,

其實(shí)他們的圖文并排的原理都是一樣的 都是NSMutableAttributedString來處理富文本

之前用TQRichTextView實(shí)現(xiàn)過emoji表情+文字 雖然性能還行,但是 計算文本高度是一個讓我非常頭疼的問題芋类,經(jīng)常容易算不準(zhǔn)隆嗅,表情的大小很難調(diào)整,今天YYLabel簡單了實(shí)現(xiàn)了一下他的emoji表情+文字的列表排布侯繁,個人感覺相當(dāng)好用 YYLabel提供計算文本的高度胖喳,性能也很好,有個異步渲染的機(jī)制贮竟,牛逼丽焊!

話不多說上代碼:

//

//??UserVC.h

//??YYTextDemo

//

//??Created?by?linpeng?on?16/3/13.

//??Copyright???2016年?ibireme.?All?rights?reserved.

//

#import

@interface?UserVC?:?UIViewController

@end

//

//??UserVC.m

//??YYTextDemo

//

//??Created?by?linpeng?on?16/3/13.

//??Copyright???2016年?ibireme.?All?rights?reserved.

//

#import?"UserVC.h"

#import?"YYText.h"

#import?"UIView+YYAdd.h"

#import?"YYImage.h"

#import?"NSBundle+YYAdd.h"

#import?"NSString+YYAdd.h"

@interface?CellModel?:?NSObject

@property?(nonatomic,strong)?YYTextLayout?*textLayout;

@property?(nonatomic)?CGFloat?cellHeight;

@end

@implementation?CellModel

@end

//=====================================分割線=========================================

@interface?UserVCCell?:?UITableViewCell

@property?(nonatomic,strong)?CellModel?*data;

@property?(nonatomic,?strong)?YYLabel?*contentLabel;

@end

@implementation?UserVCCell

#define?kWidth???280

#define?kLabelMarginTop??10

-(instancetype)initWithStyle:(UITableViewCellStyle)style?reuseIdentifier:(NSString?*)reuseIdentifier

{

self=?[super?initWithStyle:style?reuseIdentifier:reuseIdentifier];

if?(self)

{

[self?addSubview:self.contentLabel];

}

return?self;

}

-(void)setData:(CellModel?*)data

{

_data=data;

YYTextLayout?*layout=data.textLayout;

self.contentLabel.textLayout=layout;

self.contentLabel.size=layout.textBoundingSize;

}

-(YYLabel?*)contentLabel

{

if?(_contentLabel==?nil)?{

_contentLabel=?[[YYLabel?alloc]?initWithFrame:CGRectMake((kScreenWidth?-?kWidth)/2.0,?kLabelMarginTop,?0,?0)];

_contentLabel.userInteractionEnabled=YES;

_contentLabel.numberOfLines=0;

UIFont?*font=?[UIFont?systemFontOfSize:16];

_contentLabel.font=font;

_contentLabel.displaysAsynchronously=YES;?///?enable?async?display

_contentLabel.textVerticalAlignment=YYTextVerticalAlignmentTop;

[_contentLabel?setBackgroundColor:[[UIColor?grayColor]?colorWithAlphaComponent:0.2]];

}

return?_contentLabel;

}

@end

//=====================================分割線=========================================

@interface?UserVC?()

@property?(nonatomic,strong)?NSMutableArray?*dataList;

@end

@implementation?UserVC

NSMutableAttributedString?*attributeText;

-?(void)viewDidLoad?{

[super?viewDidLoad];

[self.view?setBackgroundColor:[UIColor?whiteColor]];

UITableView?*tableView=?[[UITableView?alloc]?initWithFrame:self.view.bounds];

[tableView?registerClass:[UserVCCell?class]?forCellReuseIdentifier:@"tableCell"];

tableView.delegate=self;

tableView.dataSource=self;

[self.view?addSubview:tableView];

dispatch_async(dispatch_get_main_queue(),?^{

NSMutableArray?*arrays=?[NSMutableArray?new];

for?(inti=0;?i<100;?i++)

{

NSMutableAttributedString?*text=?[NSMutableAttributedString?new];

NSString?*title11=?@"開始?";

[text?appendAttributedString:[[NSAttributedString?alloc]?initWithString:title11?attributes:nil]];

UIFont?*font=?[UIFont?systemFontOfSize:16];

NSArray?*names=?@[@"001",?@"022",?@"019",@"056",@"085",@"001",?@"022",?@"019",@"056",@"085",@"001",?@"022",?@"019",@"056",@"085",@"001",?@"022",?@"019",@"056",@"085",@"001",?@"022",@"001",@"001",@"022",@"022",@"022",@"022",@"022",@"022",@"022",@"001",@"001",@"001",@"001",@"001",@"001",@"001",@"001",@"001",@"001",@"001",@"001",@"001",@"001",@"001",@"001",@"001",@"001",@"001",@"001",@"001",@"001",@"022",@"022",@"022",@"022",@"001",?@"022",?@"019",@"056",@"085",@"001",?@"022",?@"019",@"056",@"085",@"001",?@"022",?@"019",@"056",@"085",@"001",?@"022",?@"019",@"056",@"085",@"001",?@"022",@"001",@"001",@"022",@"022",@"022",@"022",@"022",@"022",@"022",@"001",@"001",@"001",@"001",@"001",@"001",@"001",@"001",@"001",@"001",@"001",@"001",@"001",@"001",@"001",@"001",@"001",@"001",@"001",@"001",@"001",@"001",@"022",@"022",@"022",@"022"];

for?(intj=0;j

{

NSString?*name=names[j];

NSString?*path=?[[NSBundle?mainBundle]?pathForScaledResource:name?ofType:@"png"?inDirectory:@"EmoticonQQ.bundle"];

NSData?*data=?[NSData?dataWithContentsOfFile:path];

YYImage?*image=?[YYImage?imageWithData:data?scale:2];//修改表情大小

image.preloadAllAnimatedImageFrames=YES;

YYAnimatedImageView?*imageView=?[[YYAnimatedImageView?alloc]?initWithImage:image];

NSMutableAttributedString?*attachText=?[NSMutableAttributedString?yy_attachmentStringWithContent:imageView?contentMode:UIViewContentModeCenter?attachmentSize:imageView.size?alignToFont:font?alignment:YYTextVerticalAlignmentCenter];

[text?appendAttributedString:attachText];

if(arc4random()%5==0)

{

[text?appendAttributedString:[[NSAttributedString?alloc]?initWithString:@"這是亂七八糟的文字"?attributes:nil]];

}

}

[text?appendAttributedString:[[NSAttributedString?alloc]?initWithString:@"結(jié)束"?attributes:nil]];

YYTextContainer?*container=?[YYTextContainer?containerWithSize:CGSizeMake(kWidth,?MAXFLOAT)];

YYTextLayout?*textLayout=?[YYTextLayout?layoutWithContainer:container?text:text];

CellModel?*model=?[[CellModel?alloc]?init];

model.textLayout=textLayout;

model.cellHeight=textLayout.textBoundingSize.height;

[arrays?addObject:model];

}

self.dataList=arrays;

//更新UI

dispatch_async(dispatch_get_main_queue(),?^{

[tableView?reloadData];

});

});

}

-(UITableViewCell?*)tableView:(UITableView?*)tableView?cellForRowAtIndexPath:(NSIndexPath?*)indexPath

{

static?NSString?*cellID=?@"tableCell";

UserVCCell?*cell=?[tableView?dequeueReusableCellWithIdentifier:cellID];

if?(!cell)

{

cell=?[[UserVCCell?alloc]?initWithStyle:UITableViewCellStyleDefault?reuseIdentifier:cellID];

}

CellModel?*model=self.dataList[indexPath.row];

cell.data=model;

return?cell;

}

-(NSInteger)tableView:(UITableView?*)tableView?numberOfRowsInSection:(NSInteger)section

{

return?self.dataList.count;

}

-(CGFloat)tableView:(UITableView?*)tableView?heightForRowAtIndexPath:(NSIndexPath?*)indexPath

{

CellModel?*model=self.dataList[indexPath.row];

CGFloatheight=model.cellHeight;

return?height?+?2*kLabelMarginTop;

}

-?(void)didReceiveMemoryWarning?{

[super?didReceiveMemoryWarning];

//?Dispose?of?any?resources?that?can?be?recreated.

}

/*

#pragma?mark?-?Navigation

//?In?a?storyboard-based?application,?you?will?often?want?to?do?a?little?preparation?before?navigation

-?(void)prepareForSegue:(UIStoryboardSegue?*)segue?sender:(id)sender?{

//?Get?the?new?view?controller?using?[segue?destinationViewController].

//?Pass?the?selected?object?to?the?new?view?controller.

}

*/

@end

看效果??我模擬了100條數(shù)據(jù) 所以數(shù)據(jù)那用了GCD 然后更新UI


ps:正則過濾表情生成NSMutableAttributedString

正常我們使用的時候是通過一串字符串(包含表情的占位符)來對應(yīng)顯示

例如:

[嘻嘻][嘻嘻][嘻嘻]我們[喜歡][喜歡][喜歡]你們[錢][錢][錢]這樣[可愛][可愛][可愛]我的小時候[可愛][可愛][可愛][可愛][可愛]

以下利用正則表達(dá)式來過濾各個表情的位置

-(NSMutableAttributedString *)processCommentContent:(NSString *)text

{

//轉(zhuǎn)成可變屬性字符串

NSMutableAttributedString?*mAttributedString=?[[NSMutableAttributedString?alloc]init];

NSMutableParagraphStyle?*paragraphStyle=?[[NSMutableParagraphStyle?alloc]?init];

[paragraphStyle?setLineSpacing:4];//調(diào)整行間距

[paragraphStyle?setParagraphSpacing:4];//調(diào)整行間距

NSDictionary?*attri=?[NSDictionary?dictionaryWithObjects:@[kCurrentLabelFont,[UIConstants?getWordColorC2],paragraphStyle]?forKeys:@[NSFontAttributeName,NSForegroundColorAttributeName,NSParagraphStyleAttributeName]];

[mAttributedString?appendAttributedString:[[NSAttributedString?alloc]?initWithString:text?attributes:attri]];

//創(chuàng)建匹配正則表達(dá)式的類型描述模板

NSString?*pattern=?@"\\[[a-zA-Z0-9\\u4e00-\\u9fa5]+\\]";

//創(chuàng)建匹配對象

NSError?*?error;

NSRegularExpression?*regularExpression=?[NSRegularExpression?regularExpressionWithPattern:pattern?options:NSRegularExpressionCaseInsensitive?error:&error];

//判斷

if?(!regularExpression)//如果匹配規(guī)則對象為nil

{

NSLog(@"正則創(chuàng)建失敗坝锰!");

NSLog(@"error=?%@",[error?localizedDescription]);

return?nil;

}

else

{

NSArray?*resultArray=?[regularExpression?matchesInString:mAttributedString.string?options:NSMatchingReportCompletion?range:NSMakeRange(0,?mAttributedString.string.length)];

//開始遍歷?逆序遍歷

for?(NSIntegeri=resultArray.count?-?1;?i>=?0;?i?--)

{

//獲取檢查結(jié)果粹懒,里面有range

NSTextCheckingResult?*result=resultArray[i];

//根據(jù)range獲取字符串

NSString?*rangeString=?[mAttributedString.string?substringWithRange:result.range];

NSString?*imageName=??[[KSFaceManager?shareManager]?reflectFaceIDWithFace:rangeString];

if?(imageName)

{

//獲取圖片

UIImage?*image=?[self?getImageWithRangeString:imageName];//這是個自定義的方法

if?(image?!=?nil)

{

UIImageView?*imageView=?[[UIImageView?alloc]?initWithImage:image];

imageView.width=23;

imageView.height=23;

NSMutableAttributedString?*attachText=?[NSMutableAttributedString?yy_attachmentStringWithContent:imageView?contentMode:UIViewContentModeCenter?attachmentSize:imageView.size?alignToFont:[UIFont?systemFontOfSize:16]?alignment:YYTextVerticalAlignmentCenter];

//開始替換

[mAttributedString?replaceCharactersInRange:result.range?withAttributedString:attachText];

}

}

}

}

return?mAttributedString;

}

//根據(jù)rangeString獲取plist中的圖片

-(UIImage?*)getImageWithRangeString:(NSString?*)rangeString

{

return?[UIImage?imageNamed:rangeString];

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市顷级,隨后出現(xiàn)的幾起案子凫乖,更是在濱河造成了極大的恐慌,老刑警劉巖弓颈,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件帽芽,死亡現(xiàn)場離奇詭異,居然都是意外死亡翔冀,警方通過查閱死者的電腦和手機(jī)导街,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來纤子,“玉大人搬瑰,你說我怎么就攤上這事款票。” “怎么了泽论?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵艾少,是天一觀的道長。 經(jīng)常有香客問我翼悴,道長缚够,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任鹦赎,我火速辦了婚禮谍椅,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘古话。我一直安慰自己雏吭,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布煞额。 她就那樣靜靜地躺著思恐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪膊毁。 梳的紋絲不亂的頭發(fā)上胀莹,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天,我揣著相機(jī)與錄音婚温,去河邊找鬼描焰。 笑死,一個胖子當(dāng)著我的面吹牛栅螟,可吹牛的內(nèi)容都是我干的荆秦。 我是一名探鬼主播,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼力图,長吁一口氣:“原來是場噩夢啊……” “哼步绸!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起吃媒,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤瓤介,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后赘那,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體刑桑,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年募舟,在試婚紗的時候發(fā)現(xiàn)自己被綠了祠斧。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡拱礁,死狀恐怖琢锋,靈堂內(nèi)的尸體忽然破棺而出辕漂,到底是詐尸還是另有隱情,我是刑警寧澤吩蔑,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布钮热,位于F島的核電站,受9級特大地震影響烛芬,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜飒责,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一赘娄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧宏蛉,春花似錦遣臼、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至嗅义,卻和暖如春屏歹,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背之碗。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工蝙眶, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人褪那。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓幽纷,卻偏偏與公主長得像,于是被迫代替她去往敵國和親博敬。 傳聞我的和親對象是個殘疾皇子友浸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內(nèi)容