項(xiàng)目中如果只是使用幾種固定的字體,可以本地添加自定義字體,可以參考iOS加入自定義字體庫 這篇文章詳細(xì)的說明如何在本地添加自定義字體
如果本地添加的幾種字體難以滿足需求,這時候就會使用從服務(wù)器動態(tài)下發(fā)字體的方式來實(shí)現(xiàn),這時候就需要動態(tài)的向字體庫中注冊自定義字體,然后再調(diào)用[UIFont fontWithName: size:]方法設(shè)置字體
先說下思路:
- 下載字體到APP的沙盒中,并獲取到ttf文件路徑
- 判斷路徑是否存在且有效
- 使用文件路徑注冊自定義字體
- 返回字體名稱
- 調(diào)用
[UIFont fontWithName: size:]方法設(shè)置字體
思路有了,剩下的就是實(shí)現(xiàn)
在實(shí)現(xiàn)之前,還需要對功能進(jìn)行設(shè)計,比如怎么封裝才能讓這個功能簡單易用?又要對外暴露哪些接口?效率等都是需要我們考慮的
在項(xiàng)目中,這個下載應(yīng)該分屬于下載模塊,對于我們封裝注冊字體是不需要管的,同時,項(xiàng)目中注冊的字體可能有很多,這個根據(jù)需求來定,所以我們可以使用單例實(shí)現(xiàn)這個功能。
記住我們的目標(biāo):給我一個字體路徑,我就返回給你一個字體名稱
1. 設(shè)計對外提供的接口
為了調(diào)用的方便性,我們可以對外暴露一個類方法供使用者調(diào)用
+ (NSString *)registerFontWithPath:(NSString *)path;
2. 參數(shù)合法性校驗(yàn)
在實(shí)現(xiàn)內(nèi)部,我們需要判斷參數(shù)的合法性
BOOL isDir;
BOOL isExist = [[NSFileManager defaultManager] fileExistsAtPath:fontPath isDirectory:&isDir];
// 路徑是否存在,且路徑非目錄
if (fontPath.length <= 0 || !isExist || (isExist && isDir)) {
return nil;
}
3. 注冊字體并返回
NSURL *fontUrl = [NSURL fileURLWithPath:fontPath];
CGDataProviderRef fontDataProvider = CGDataProviderCreateWithURL((__bridge CFURLRef)fontUrl);
CGFontRef fontRef = CGFontCreateWithDataProvider(fontDataProvider);
CGDataProviderRelease(fontDataProvider);
CTFontManagerRegisterGraphicsFont(fontRef, NULL);
fontName = CFBridgingRelease(CGFontCopyPostScriptName(fontRef));
CGFontRelease(fontRef);
return fontName;
到這里,動態(tài)注冊字體的介紹已經(jīng)結(jié)束。
這樣的設(shè)計雖然可以,但是為了app的性能,在這個單例里面還可以> 再加入字體緩存,當(dāng)同一個字體路徑多次請求的時候,只需要先查找> 緩存中是否有該字體,有的話直接從緩存中獲取即可,這樣可以避免> 重復(fù)的注冊字體浪費(fèi)資源。
參照iOS方法查找