1. 程式人生 > >iOS之UI--富文字總結

iOS之UI--富文字總結

文章內容大綱

  • 1、NSMutableAttributedString的基本使用
  • 2、NSMutableAttributedString的簡易封裝
  • 3、使用開原始碼GOBMarkupPaser處理富文字
  • 4、UITextKit簡介
  • 5、程式設計思想的相關思考

前言

富文字使用案例:

這裡我自己也用了富文字實現了簡單的卻也是常用的例子:

                             對於最後面的¥50中劃線這種設定,估計只有富文字最好用了。

  • 在IOS或者Mac OS X通過UIKit提供的用來顯示字串控制元件有三個:
    • UILable,UITextField,UITextView。

然而這些控制元件本身對文字的展現方式很單一,通常僅僅能夠控制字型樣式、大小、顏色、加粗、斜體等等,而對於行距控制,字距控制,段落控制等高階功能卻無能為力。

此時不免要提起一個非常強大的文字排版框架CoreText.framework

CoreText框架是基於 iOS 3.2+ 和 OSX 10.5+ 的一種能夠對文字格式和文字佈局進行精細控制的文字引擎。它良好的結合了 UIKit 和 Core Graphics/Quartz:

UIKit 的 UILabel 允許你通過在 IB 中簡單的拖曳新增文字,但你不能改變文字的顏色和其中的單詞。

Core Graphics/Quartz幾乎允許你做任何系統允許的事情,但你需要為每個字形計算位置,並畫在螢幕上。

CoreText正結合了這兩者!你自己可以完全控制位置、佈局、類似文字大小和顏色這樣的屬性,CoreText將幫你完善其它的東西??類似文字換行、字型呈現等等。

然而,CoreText.framework本身非常龐大,學習成本較高,使用起來也不是很方便,所以一般不是特殊需要,很少會有人去使用它

隨 著iOS6 API的釋出,文字顯示的API越來越完善,其中一個重要的更新是在UITextField,UITextView和UILabel中加入了對 AttributedString的支援,實現行距控制,字距控制,段落控制等高階功能也不必再去使用深奧的CoreText框架。

而iOS7的釋出,蘋果又引入了TextKit,TextKit是一個快速而又現代化的文字排版和渲染引擎。

TextKit並沒有新增類,只是在原有的文字顯示控制元件上進行了封裝,可以在平時我們最喜歡使用的UILabel,UITextField,UITextView等控制元件裡面使用,其最主要的作用就是為程式提供文字排版和渲染的功能。

蘋 果引入TextKit的目的並非要取代已有的CoreText框架,雖然CoreText的主要作用也是用於文字的排版和渲染,但它是一種先進而又處於底 層技術,如果我們需要將文字內容直接渲染到圖形上下文(Graphics context)時,從效能和易用性來考慮,最佳方案就是使用CoreText。而如果我們需要直接利用蘋果提供的一些控制元件(如UITextView、 UILabel和UITextField等)對文字進行排版,那麼藉助於UIKit中TextKit提供的API無疑更為方便快捷。

TextKit在文書處理方面具有非常強大的功能,並且開發者可以對TextKit進行定製和擴充套件。據悉,蘋果利用了2年的時間來開發TextKit,相信這對許多開發者來說都是福音。

IOS之NSMutableAttributedString 使用詳解

1、NSMutableAttributedString的基本使用

  • 富文字注意:
    • 先設定的先顯示,後設置的,如果和先設定的樣式不一致,是會覆蓋的,富文字的設定具有先後順序。
    • 不要忽略了空格也是一個字元。
    • 建議使用靈活的好用的NSMutableAttributedString,不要使用NSAttributedString。

富文字基本使用方法的思路概要

1、建立一個NSMutableAttributedString富文字物件(一般不用NSAttributedString)
2、設定addAttribute屬性
    (1) addAttribute: 一個屬性
    (2) addAttributes: 一個儲存多個屬性的屬性字典,比如這個字典可以是:
        NSDictionary *attrDic = @{ 
                NSFontAttributeName: [UIFont fontWithName: @"Zapfino" size: 15],                               
                NSForegroundColorAttributeName: [UIColor blueColor] 
        }; 
3、控制元件.attributedText = 富文字物件(和控制元件.txt = NSString文字物件不一樣的)

示例富文字使用過程:

其中AttributedString究竟可以設定哪些屬性,具體來說,有以下21個:

NSFontAttributeName                設定字型屬性,預設值:字型:Helvetica(Neue) 字號:12
NSForegroundColorAttributeNam      設定字型顏色,取值為 UIColor物件,預設值為黑色
NSBackgroundColorAttributeName     設定字型所在區域背景顏色,取值為 UIColor物件,預設值為nil, 透明色
NSLigatureAttributeName            設定連體屬性,取值為NSNumber 物件(整數),0 表示沒有連體字元,1 表示使用預設的連體字元
NSKernAttributeName                設定字元間距,取值為 NSNumber 物件(整數),正值間距加寬,負值間距變窄
NSStrikethroughStyleAttributeName  設定刪除線,取值為 NSNumber 物件(整數)
NSStrikethroughColorAttributeName  設定刪除線顏色,取值為 UIColor 物件,預設值為黑色
NSUnderlineStyleAttributeName      設定下劃線,取值為 NSNumber 物件(整數),列舉常量 NSUnderlineStyle中的值,與刪除線類似
NSUnderlineColorAttributeName      設定下劃線顏色,取值為 UIColor 物件,預設值為黑色
NSStrokeWidthAttributeName         設定筆畫寬度,取值為 NSNumber 物件(整數),負值填充效果,正值中空效果
NSStrokeColorAttributeName         填充部分顏色,不是字型顏色,取值為 UIColor 物件
NSShadowAttributeName              設定陰影屬性,取值為 NSShadow 物件
NSTextEffectAttributeName          設定文字特殊效果,取值為 NSString 物件,目前只有圖版印刷效果可用:
NSBaselineOffsetAttributeName      設定基線偏移值,取值為 NSNumber (float),正值上偏,負值下偏
NSObliquenessAttributeName         設定字形傾斜度,取值為 NSNumber (float),正值右傾,負值左傾
NSExpansionAttributeName           設定文字橫向拉伸屬性,取值為 NSNumber (float),正值橫向拉伸文字,負值橫向壓縮文字
NSWritingDirectionAttributeName    設定文字書寫方向,從左向右書寫或者從右向左書寫
NSVerticalGlyphFormAttributeName   設定文字排版方向,取值為 NSNumber 物件(整數),0 表示橫排文字,1 表示豎排文字
NSLinkAttributeName                設定連結屬性,點選後呼叫瀏覽器開啟指定URL地址
NSAttachmentAttributeName          設定文字附件,取值為NSTextAttachment物件,常用於文字圖片混排
NSParagraphStyleAttributeName      設定文字段落排版格式,取值為 NSParagraphStyle 物件

關於屬性的具體如何使用,對於不熟悉的屬性可以通過搜尋引擎瞭解。

還可以直接到UIKIt框架底層去查詢:

注意:是UIKit框架下的NSAttributedString.h,而不是Foundation框架下的NSAttributedString.h去查,Foundation框架下雖然有NSAttributedString.h,但是Foundation框架沒有關於富文字所有的key,而且和UIKit完全不一樣的工具類。

2、NSMutableAttributedString的簡易封裝

寫出思路:

根據NSMutableAttributedString的基本使用,我們每次需要設定富文字,都需要建立NSMutableAttributedString並呼叫相同的add...方法。
那麼,就可以先建立一個類,並把這個add...方法抽離出來放進這個類中,類似MVC的抽離模型資料物件。
這個類是屬性模型物件,而不是資料模型物件哦。說法不一,但本質其實一樣的。

3、使用開原始碼GOBMarkupPaser處理富文字

github描述的雖然比較多,但是用起來還是比較容易的。下面只要跑一下程式,原始碼中也有demo,先看看原始碼執行的程式效果:

因為這個開原始碼GONMarkupParser處理富文字比較方便,所以以後開發專案建議使用。

4、UITextKit簡介

什麼是UITextKit?

TextKit是在iOS7中新出的,實現了對CoreText的封裝,使用起來更加方便.

雖然是新出的,但也不代表立馬就能上手-_-!!,TextKit可以實現圖文混排效果,很好用.

實現的過程如下:

storage --> layoutManager --> textContainer --> textView

這.....顯示一串文字就要做這麼多的事情.....

一下圖中程式碼例項是實現 高亮某些文字:

什麼時候使用UITextKit?

圖文混排,但並不是什麼時候要實現圖文混排就要用這個,比如有的app鳳凰新聞客戶端就不是,但是可以使用UITextKit實現稍微簡單的圖文混搭的介面。

只需要瞭解一下有UITextKit這麼個東西,其實這個UITextKit可以用來實現一個簡易的電子書閱讀器。

 Bezier n. 貝齊爾;貝塞爾曲線   exclusion n. 拒絕,排除 小專案實現電子書:BookTextView例項效果動態圖: 小專案實現電子書:BookTextView中的ViewController上的程式碼
 1 #import "ViewController.h"
 2 #import "ParagraphAttributes+Constructor.h"
 3 #import "ExclusionView.h"
 4 #import "BookTextView.h"
 5 
 6 #define  Width                             [UIScreen mainScreen].bounds.size.width
 7 #define  Height                            [UIScreen mainScreen].bounds.size.height
 8 
 9 @interface ViewController ()<UITextViewDelegate>
10 
11 @property (strong, nonatomic) BookTextView *bookView;
12 
13 @end
14 
15 @implementation ViewController
16 
17 - (void)viewDidLoad {
18     [super viewDidLoad];
19     
20     
21     // 讀取文字
22     NSString *text = [NSString stringWithContentsOfFile:[NSBundle.mainBundle URLForResource:@"lorem" withExtension:@"txt"].path
23                                                encoding:NSUTF8StringEncoding
24                                                   error:nil];
25     
26     
27     // 初始化bookView
28     self.bookView                     = [[BookTextView alloc] initWithFrame:CGRectMake(10, 10, Width - 20, Height - 20)];
29     self.bookView.textString          = text;
30     
31     // 設定段落樣式
32     self.bookView.paragraphAttributes = [ParagraphAttributes qingKeBengYue];
33     
34     // 設定富文字
35     self.bookView.attributes          = @[[ConfigAttributedString foregroundColor:[[UIColor blackColor] colorWithAlphaComponent:0.75f]
36                                                                             range:NSMakeRange(0, 9)],
37                                           [ConfigAttributedString font:[UIFont fontWithName:QingKeBengYue size:22.f]
38                                                                  range:NSMakeRange(0, 9)]];
39     
40     // 載入圖片
41     ExclusionView *exclusionView = [[ExclusionView alloc] initWithFrame:CGRectMake(150.f, 195, 320, 150)];
42     self.bookView.exclusionViews = @[exclusionView];
43     UIImageView *imageView       = [[UIImageView alloc] initWithFrame:exclusionView.bounds];
44     imageView.image              = [UIImage imageNamed:@"demo"];
45     [exclusionView addSubview:imageView];
46     
47     
48     // 構建view
49     [self.bookView buildWidgetView];
50     [self.view addSubview:self.bookView];
51     
52     
53     // 延時0.01s執行
54     [self performSelector:@selector(event)
55                withObject:nil
56                afterDelay:0.01];
57 }
58 
59 - (void)event {
60     [self.bookView moveToTextPercent:0.00];
61 }
62 
63 @end
 

5、程式設計思想的相關思考

    在使用了UIKit的BookTextView的例項中,因為用到了自定義View,然後需要在自定義View上顯示富文字。由於富文字的設定可以由 多個不同的屬性值,比如:字型大小,文字前景色,背景色等等,所以需要抽離出來新建一個屬性-值模型物件,每個物件儲存一種屬性-值,然後在自定義 View中新增property的NSArray,用來儲存和重寫set方法載入傳進來的屬性-值模型物件,然後通過文字物件對應的還未設定屬性可變富文 本物件add這些屬性-值模型物件儲存的值。當然這個BookTextView內部因為用到UIKit所以是通過NSTextStorage *storage通過遍歷方法add載入NSArray物件儲存的屬性-值。

  而在HYStringAttribute例項中,因為僅僅 需要直接將NSString物件對應的富文字物件設定屬性,最後新增到Label等控制元件上顯示,因為考慮到簡易封裝的需求,所以特地將所有的屬性抽象成一 個需要協議約束的抽象類,然後由這個抽象類具體派生出具體的屬性物件,比如Font物件,前景色物件,背景色物件.....這裡只實現了三種,還有很多待 有時間按需求去拓展。具體使用的時候,需要通過類別拓展方法來方便使用:<1>一種是富文字類拓展出方法,這個方法實現通過引數傳入的具體的 屬性物件,然後載入這個物件,設定富文字屬性。<2>一種是NSString類拓展出方法,這個方法直接將本身例項物件self通過富文字創 建和載入通過引數傳入的具體的屬性物件,然後返回設定好富文字屬性的富文字物件。