做 App 時(shí),設(shè)置頁(yè)里加一個(gè)「大號(hào)字體 / 關(guān)懷模式」開(kāi)關(guān),聽(tīng)起來(lái)簡(jiǎn)單,真做起來(lái)往往是一地雞毛:每個(gè) UILabel 手寫(xiě) if isLarge { font = 22 } else { 15 },UIButton 還要分 normal/selected,UserDefaults 要記得存,切換時(shí)還得挨個(gè)頁(yè)面刷新……
最近我把這套能力整理成獨(dú)立庫(kù) XPFontSizeManage,并發(fā)布了 1.0.0 穩(wěn)定版,已推送到 CocoaPods 公有源 和 GitHub。本文介紹它的設(shè)計(jì)思路與用法,方便你在項(xiàng)目里直接接入。
一、它解決什么問(wèn)題?
XPFontSizeManage 是一個(gè)輕量級(jí) UIKit 庫(kù),核心能力是:
- 在 App 內(nèi)維護(hù) 普通(normal)/ 大號(hào)(large) 兩檔 UI 模式;
- 用 聲明式 的方式描述兩套資源(字體、顏色、邊距、圓角等);
- 切換模式后,已綁定的控件自動(dòng)刷新,無(wú)需滿屏
if/else; - 模式 持久化 到
UserDefaults,下次啟動(dòng)保持用戶選擇。
主場(chǎng)景是 適老化、無(wú)障礙、設(shè)置頁(yè)「字體大小」。以字號(hào)為主,也支持顏色、邊距、圓角等配套(關(guān)懷模式里字號(hào)變大后,按鈕邊距、對(duì)比度往往也要一起調(diào))。
二、核心設(shè)計(jì)(三層架構(gòu))
XPFontSizeManager(全局檔位 + 持久化 + 通知)
↓ fontSizeDidChangeNotification
MixedResource<T>(normal / other → unfold())
↓
UIKit Extension(UILabel / UIButton / UIView / CALayer …)
-
XPFontSizeManager:?jiǎn)我粩?shù)據(jù)源,切換時(shí)發(fā)
fontSizeDidChangeNotification。 -
MixedResource<T>:泛型雙態(tài)資源,
unfold()按當(dāng)前檔位返回normal或other。 -
UIKit 擴(kuò)展:關(guān)聯(lián)對(duì)象保存配置 + 監(jiān)聽(tīng)通知,自動(dòng)寫(xiě)回
font、textColor、cornerRadius等。
低侵入:不用子類化控件,現(xiàn)有頁(yè)面加幾行綁定即可。
三、安裝
CocoaPods(推薦,1.0.0 已上 Trunk):
pod 'XPFontSizeManage', '~> 1.0.0'
pod install
源碼:
- GitHub:https://github.com/jamalping/XPFontSizeManage
- Gitee 鏡像:https://gitee.com/jamalping/XPFontSizeManage
要求:iOS 9.0+,Swift 5.0+。
四、快速上手
1. 切換全局模式
import XPFontSizeManage
// 設(shè)置頁(yè)開(kāi)關(guān)
XPFontSizeManager.switchFontSize()
// 或直接指定(會(huì)持久化并廣播通知)
XPFontSizeManager.fontSize = .large
if XPFontSizeManager.isLargeFont {
// 當(dāng)前為大號(hào)模式
}
業(yè)務(wù)層也可監(jiān)聽(tīng)統(tǒng)一通知:
NotificationCenter.default.addObserver(
forName: XPFontSizeManager.fontSizeDidChangeNotification,
object: nil,
queue: .main
) { _ in
// 刷新自定義 UI
}
2. 文本控件綁定字體
let label = UILabel()
label.text = "標(biāo)題"
// 直接屬性
label.fontSize = MixFont(
normal: .systemFont(ofSize: 15),
other: .systemFont(ofSize: 22)
)
// xp 命名空間(等價(jià))
label.xp.fontSize = MixFont(normal: .systemFont(ofSize: 15), other: .systemFont(ofSize: 22))
// 按字號(hào)差值快速構(gòu)造
label.fontSize = XPFont(normal: .systemFont(ofSize: 15), 3) // 大號(hào) = 18pt
UITextField、UITextView 用法相同。
3. UIButton:分狀態(tài)字體 / 顏色 / 邊距
button.xpControlNormalFont = MixFont(normal: .systemFont(ofSize: 15), other: .systemFont(ofSize: 22))
button.xpControlSelectedFont = MixFont(normal: .boldSystemFont(ofSize: 16), other: .boldSystemFont(ofSize: 24))
button.xpControlNormalTitleColor = MixColor(normal: .white, other: UIColor(white: 1.0, alpha: 0.92))
button.xpControlNormalInset = MixImageEdgeInset(
normal: .zero,
other: UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 0)
)
4. 自定義邏輯 & Layer
// UIView:任意自定義刷新
view.fontSizeChangeCallBack = { size in
view.alpha = (size == .large) ? 1.0 : 0.7
}
// CALayer:圓角、邊框隨模式變化
view.layer.xpCornerRadius = MixedResource(normal: 8, other: 20)
view.layer.xpBorderWidth = MixedResource(normal: 2, other: 6)
5. 移除監(jiān)聽(tīng)
動(dòng)態(tài)場(chǎng)景可將 fontSize 置為 nil,或調(diào)用 removeAllFontSizeObservers(),避免多余監(jiān)聽(tīng)。
五、和系統(tǒng) Dynamic Type 的區(qū)別?
| 系統(tǒng) Dynamic Type | XPFontSizeManage | |
|---|---|---|
| 觸發(fā) | 系統(tǒng)「輔助功能 → 更大字體」 | App 內(nèi)獨(dú)立開(kāi)關(guān)(關(guān)懷模式) |
| 檔位 | 多級(jí)連續(xù)縮放 | 固定兩檔,布局可控 |
| 范圍 | 主要影響字體 | 字體 + 顏色 + 邊距 + 圓角等 |
二者可并存:系統(tǒng)字號(hào)交給 UIFontMetrics,業(yè)務(wù)關(guān)懷模式交給本庫(kù)。
六、Example 與質(zhì)量
倉(cāng)庫(kù)自帶 Example 演示:文本三種綁定方式、Button 分狀態(tài)、Layer/回調(diào)、移除監(jiān)聽(tīng)等;含單元測(cè)試與 GitHub Actions CI。
本地運(yùn)行:
git clone https://github.com/jamalping/XPFontSizeManage.git
cd XPFontSizeManage/Example
pod install
open XPFontSizeManage.xcworkspace
七、版本與鏈接
- 當(dāng)前穩(wěn)定版:1.0.0(MIT 協(xié)議)
- 1.0 起 API 統(tǒng)一為
XP/xp前綴 - GitHub:https://github.com/jamalping/XPFontSizeManage
-
CocoaPods:
pod 'XPFontSizeManage', '~> 1.0.0'
歡迎 Star、Issue 和 PR。若你在做適老化或設(shè)置頁(yè)字號(hào)方案,希望這個(gè)庫(kù)能少寫(xiě)一些重復(fù)代碼。
作者:jamalping · 開(kāi)源地址見(jiàn)上文 GitHub