仿鬥魚聊天:基於CoreText的物件導向圖文排版工具AWRichText

hard_man發表於2019-03-01

AWRichText

基於CoreText,物件導向,極簡,易用,高效,支援精確點選,UIView混排,GIF動圖,並不僅僅侷限於圖文混排的富文字排版神器。

程式碼地址:https://github.com/hardman/AWRichText -- 喜歡的同學可以star。

接下來會在blog中更新一些具體實現細節。

簡述

很多app中都有聊天功能,圖文混排也是常見的需求。

iOS原生類:NSAttributedString 就是支援圖文混排的。很多應用會用它來實現自己的功能。

但是直接使用它會有很多不方便的地方,大概有下面幾個:

  1. 太難用,屬性那麼多,而且使用字典構造,每次用都要查一下文件。更不要說大規模使用了
  2. 不支援GIF動圖
  3. 不支援區域性精確點選
  4. 不支援UIView與文字進行混排

AWRichText完全解決了這些問題,它的特點如下:

  1. 基於 NSAttributedString+CoreText 繪製
  2. 物件導向+鏈式操作,不需記憶繁多的屬性名即可快速生成各種文字效果
  3. 支援GIF 及 任意UIView 的圖文混排
  4. 支援精確點選

AWRichText是可以讓你在專案中大規模使用的,並不僅僅侷限於圖文混排的工具。

它適合於如下場景:文字+文字,圖片+文字,元件(UIView及其子類)+文字。

因此可出現在:文件排版聊天排版列表展示廣告文案 等各個位置。

功能演示

AWRichText演示

圖中的Demo(直接下載github程式碼執行即可)包含4部分:

  • 第一部分展示了長文字圖文混排功能。展示了文字樣式,UIView(一個無處安放的按鈕)混排,精確點選(藍紫色字型),GIF動圖(小龍)。
  • 第二部分展示了富文字的更多使用方式。可以在任意頭像+暱稱這種列表中使用,省去動態建立UIImageView和UILabel的麻煩。
  • 第三部分展示了一個簡單的的仿鬥魚聊天功能。展示瞭如何建立複雜的富文字及獲取富文字尺寸等功能。
  • 第四部分展示了純UIView單行排版功能:對於按鈕橫排的需求很實用,另外點選"開啟DebugFrame"按鈕,會觸發線框模式,能夠看到每個文字的位置和大小。

Demo中所有元素都是使用AWRichText構造的。

使用方法

1.直接引入檔案

將程式碼中的 "RichText" 資料夾直接拖入你的工程。 引入標頭檔案 "AWRichText.h" 即可使用。

2.使用pod

在Podfile檔案中加入:

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'

target 'TargetName' do
pod 'AWRichText', '~> 1.0.1'
end
複製程式碼

然後命令列執行如下命令:

pod install
複製程式碼

基本用法

#include "AWRichText.h"

...
...

AWRichText *richText = [[AWRichText alloc] init];
    
//建立紅色文字hello,文字型別 text和font是必須設定的。
AWRTTextComponent *rTextComp = [[AWRTTextComponent alloc] init]
.AWText(@"hello")
.AWColor([UIColor redColor])
.AWFont([UIFont systemFontOfSize:12])
.AWPaddingRight(@1);
[richText addComponent: rTextComp];
    
//建立藍色文字world
AWRTTextComponent *bTextComp = [[AWRTTextComponent alloc] init]
.AWText(@" world")
.AWColor([UIColor blueColor ])
.AWFont([UIFont systemFontOfSize:12])
.AWPaddingRight(@1);
[richText addComponent:bTextComp];
    
//建立圖片,圖片型別也請設定font,否則可能顯示異常
AWRTImageComponent *imgComp = [[AWRTImageComponent alloc] init]
.AWImage([UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"fengtimo.jpg" ofType:nil]])
.AWFont([UIFont systemFontOfSize:12])
.AWBoundsDepend(@(AWRTAttchmentBoundsDependFont))
.AWAlignment(@(AWRTAttachmentAlignCenter))
.AWPaddingRight(@1);
[richText addComponent:imgComp];
    
//建立UIButton
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 120, 22)];
btn.titleLabel.font = [UIFont systemFontOfSize:12];
[btn setTitle:@"這是一個button" forState:UIControlStateNormal];
[btn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[btn setTitleColor:[UIColor colorWithRed:170.f/255 green:170.f/255 blue:170.f/255 alpha:1] forState:UIControlStateHighlighted];
[btn setBackgroundColor:[UIColor colorWithRed:1 green:184.f/255 blue:0 alpha:1]];
btn.layer.cornerRadius = 5;
btn.layer.borderWidth = 1/[UIScreen mainScreen].scale;
btn.layer.borderColor = [UIColor colorWithRed:201.f/255 green:201.f/255 blue:201.f/255 alpha:1].CGColor;

//根據button建立ViewComponent,View型別也請設定font,否則可能顯示異常
//另外 AWRTxxxComponent元件也可以從Pool中取,直接呼叫addComponentFromPoolWithType:方法。
//此種方法適合AWRichText的components變化頻繁的情況。
//正常情況使用 alloc init的方式生成即可。
((AWRTViewComponent *)[richText addComponentFromPoolWithType:AWRTComponentTypeView])
.AWView(btn)
.AWFont([UIFont systemFontOfSize:12])
.AWBoundsDepend(@(AWRTAttchmentBoundsDependContent))
.AWAlignment(@(AWRTAttachmentAlignCenter));

//建立label,AWRichTextLabel是UILabel的子類
AWRichTextLabel *awLabel = [richText createRichTextLabel];
//請務必設定rtFrame屬性,設定後會自動計算frame的尺寸
//寬度為非0,高度為0表示高度自適應。另外若寬度設定特別大,超出文字內容,最終生成的寬度仍然是以文字內容寬度為準。
//寬度為0表示單行。
//系統屬性numberOfLines無效
awLabel.rtFrame = CGRectMake(100, 100, 100, 0);
    
awLabel.backgroundColor = [UIColor colorWithRed:0.9f green:0.9f blue:0.9f alpha:1];
    
[superView addSubview:awLabel];
...
...

複製程式碼

上述程式碼效果:

1 . 當rtFrame為 CGRectMake(100,100,100,0)時:

寬度為100

2 . 當rtFrame為 CGRectMake(100,100,1000,0)時:

寬度為1000

其他用法及效果實現,詳見github中的demo。

相關文章