一咒吐、簡(jiǎn)介
UIFont類提供了用于獲取和設(shè)置字體信息的接口。類提供了訪問字體的特點(diǎn)属划,還提供了訪問恬叹,這是在布局過程中中使用的字體的字形信息系統(tǒng)。他們通過接受它們作為參數(shù)的方法同眯,您可以使用字體對(duì)象绽昼。下面依據(jù)源碼順序,分門別類詳細(xì)測(cè)試講解须蜗。
二硅确、測(cè)試與詳解
1、創(chuàng)建字體(Creating Fonts)
// 根據(jù)用戶設(shè)定的字體大小及粗細(xì)設(shè)置字體
@available(iOS 7.0, *)
open class func preferredFont(forTextStyle style: UIFontTextStyle) -> UIFont
// 根據(jù)系統(tǒng)的用戶偏好設(shè)置及設(shè)備的SizeClass 創(chuàng)建字體
@available(iOS 10.0, *)
open class func preferredFont(forTextStyle style: UIFontTextStyle, compatibleWith traitCollection: UITraitCollection?) -> UIFont
// 根據(jù)字體的名字及字體的大小創(chuàng)建字體
public init?(name fontName: String, size fontSize: CGFloat)
// 這個(gè)方法是在現(xiàn)有字體基礎(chǔ)上獲取一個(gè)不同大小的字體
open func withSize(_ fontSize: CGFloat) -> UIFont
// 根據(jù)描述符及字體的大小去創(chuàng)建Font
@available(iOS 7.0, *)
public init(descriptor: UIFontDescriptor, size pointSize: CGFloat)
通過上面第一二個(gè)API設(shè)置之后明肮,文本控件中的字體就會(huì)以用戶的偏好設(shè)定去顯示菱农,但是如果程序在運(yùn)行的時(shí)候,用戶設(shè)置修改了字體柿估,此時(shí)再切回程序循未,字體并不會(huì)自動(dòng)的跟著變★啵基于以上的原因的妖,在iOS10以下的系統(tǒng),開發(fā)者需要監(jiān)聽 UIContentSizeCategoryDidChangeNotification
通知足陨,來重新設(shè)置字體嫂粟。在iOS10以后,需要設(shè)置文字控件的屬性 adjustsFontForContentSizeCategory
為true钠右。
① 首先測(cè)試一下 UIFontTextStyle 的各種樣式赋元,樣式如下
// 標(biāo)題1樣式
@available(iOS 9.0, *)
public static let title1: UIFontTextStyle
// 標(biāo)題2樣式
@available(iOS 9.0, *)
public static let title2: UIFontTextStyle
// 標(biāo)題3樣式
@available(iOS 9.0, *)
public static let title3: UIFontTextStyle
// 大標(biāo)題樣式
@available(iOS 7.0, *)
public static let headline: UIFontTextStyle
// 小標(biāo)題樣式
@available(iOS 7.0, *)
public static let subheadline: UIFontTextStyle
// 主內(nèi)容樣式
@available(iOS 7.0, *)
public static let body: UIFontTextStyle
// 插圖樣式
@available(iOS 9.0, *)
public static let callout: UIFontTextStyle
// 腳注樣式
@available(iOS 7.0, *)
public static let footnote: UIFontTextStyle
// 說明1樣式
@available(iOS 7.0, *)
public static let caption1: UIFontTextStyle
// 說明2樣式
@available(iOS 7.0, *)
public static let caption2: UIFontTextStyle
測(cè)試代碼如下:
// MARK: 測(cè)試 preferredFont
func testFontTextStyle() {
self.addFontLabelWithTextStyle(style: .title1);
self.addFontLabelWithTextStyle(style: .title2);
self.addFontLabelWithTextStyle(style: .title3);
self.addFontLabelWithTextStyle(style: .headline);
self.addFontLabelWithTextStyle(style: .subheadline);
self.addFontLabelWithTextStyle(style: .body);
self.addFontLabelWithTextStyle(style: .callout);
self.addFontLabelWithTextStyle(style: .footnote);
self.addFontLabelWithTextStyle(style: .caption1);
self.addFontLabelWithTextStyle(style: .caption2);
}
// 添加label
func addFontLabelWithTextStyle(style: UIFontTextStyle) {
let label = UILabel.init(frame: CGRect.init(x: 40, y: 80 + self.textStyleIndex * 40, width: 400, height: 20));
label.text = String(style.rawValue);
label.font = UIFont.preferredFont(forTextStyle: style);
self.view.addSubview(label);
self.textStyleIndex += 1;
}
測(cè)試結(jié)果如下圖
②測(cè)試一下 UIContentSizeCategoryDidChangeNotification
測(cè)試代碼如下:
// MARK: 測(cè)試 preferredFont 監(jiān)聽通知
func testPreferredFontNotify() {
NotificationCenter.default.addObserver(self, selector: #selector(resetLabelStyle(notification:)), name: NSNotification.Name.UIContentSizeCategoryDidChange, object: nil)
}
// 回調(diào)通知
func resetLabelStyle(notification: Notification) {
self.view.subviews.forEach { (view) in
if view is UILabel {
let label = view as! UILabel;
let style = label.font.fontDescriptor.object(forKey: UIFontDescriptorTextStyleAttribute) as! String
label.font = UIFont.preferredFont(forTextStyle: UIFontTextStyle(rawValue: style));
}
};
}
接下來更改字體的大小及粗細(xì)等,路徑如下:
設(shè)置\通用\輔助功能
更改設(shè)置完畢(增加字體的字號(hào))后,切換到測(cè)試程序飒房,截圖如下:
③ 測(cè)試一下iOS10 新添加的文字控件屬性搁凸,更新系統(tǒng)字體。
在iOS10中狠毯,蘋果在UILabel中提供了一個(gè)新的屬性 adjustsFontForContentSizeCategory
,將其設(shè)置為True护糖,就可以了自動(dòng)更新了,不用監(jiān)聽那個(gè)通知了嚼松。
如下:
label.adjustsFontForContentSizeCategory = true;
經(jīng)過和與第二條的通知測(cè)試一樣的流程嫡良,結(jié)果一致锰扶。
④ 粗略講一下 UITraitCollection
為了表征 Size Classes
,Apple 在 iOS 8 中引入了一個(gè)新的類寝受,UITraitCollection
坷牛。這個(gè)類封裝了像水平和豎直方向的 Size Class
等信息。iOS 8 的 UIKit 中大多數(shù) UI 的基礎(chǔ)類 (包括 UIScreen很澄,UIWindow京闰,UIViewController 和 UIView) 都實(shí)現(xiàn)了 UITraitEnvironment
這個(gè)接口,通過其中的 traitCollection
這個(gè)屬性甩苛,我們可以拿到對(duì)應(yīng)的 UITraitCollection 對(duì)象蹂楣,從而得知當(dāng)前的 Size Class,并進(jìn)一步確定界面的布局讯蒲。
UIViewController 默認(rèn)遵循了UITraitEnvironment
協(xié)議痊土,用來監(jiān)聽 traitCollection 的變化,如下:
@available(iOS 8.0, *)
public func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?)
測(cè)試一下, 在VC中添加如下代碼:
// MARK: 測(cè)試 UITraitCollection
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
print(previousTraitCollection ?? "測(cè)試沒有獲取到TraitCollection");
guard previousTraitCollection != nil else {
return;
}
self.view.subviews.forEach { (view) in
if view is UILabel {
let label = view as! UILabel;
let style = label.font.fontDescriptor.object(forKey: UIFontDescriptorTextStyleAttribute) as! String
label.font = UIFont.preferredFont(forTextStyle: UIFontTextStyle(rawValue: style), compatibleWith: previousTraitCollection);
}
};
}
運(yùn)行程序墨林,并切換橫豎屏赁酝,打印如下:
測(cè)試沒有獲取到TraitCollection
<
UITraitCollection: 0x6000000daa90;
_UITraitNameUserInterfaceIdiom = Phone,
_UITraitNameDisplayScale = 2.000000,
_UITraitNameDisplayGamut = sRGB,
_UITraitNameHorizontalSizeClass = Compact, _UITraitNameVerticalSizeClass = Regular,
_UITraitNameTouchLevel = 0,
_UITraitNameInteractionModel = 1,
_UITraitNameUserInterfaceStyle = 1,
_UITraitNameLayoutDirection = 0,
_UITraitNameForceTouchCapability = 1, _UITraitNamePreferredContentSizeCategory = UICTContentSizeCategoryL
>
在第一次運(yùn)行的時(shí)候,并沒有獲取到當(dāng)前的 TraitCollection
,切換后猜得到更改后的 TraitCollection
萌丈,在切回來的時(shí)候赞哗,也會(huì)打印。
但是在界面上并沒有發(fā)現(xiàn)字體有什么變化辆雾,暫時(shí)沒有想到用到第二個(gè)方法去測(cè)試肪笋,這里猜測(cè)是用來匹配自動(dòng)布局的時(shí)候,字體的縮放度迂。
⑤ 了解一下 UIFontDescriptor
字體描述符
UIFontDescriptor
,即用屬性字典描述字體的機(jī)制藤乙。
可以通過字體描述符創(chuàng)建字體,也可以通過字體描述符中的屬性字典的更改來更改字體惭墓。
字體描述符并非字體坛梁,兩者是不同的概念,但是二者可進(jìn)行相互轉(zhuǎn)化腊凶。一個(gè) UIFont
對(duì)象通過其 fontDescriptor
獲得其對(duì)應(yīng)的字體描述符划咐,而UIFont
通過初始化函數(shù) init(descriptor:size:)
可根據(jù)字體描述符獲取對(duì)應(yīng)的字體。
更多關(guān)于 UIFontDescriptor
的初始化钧萍、屬性褐缠、方法等可參考蘋果文檔,已經(jīng)詳細(xì)表述了风瘦,之后有需要也會(huì)寫篇文章測(cè)試記錄下队魏。
二、創(chuàng)建系統(tǒng)字體(Creating System Fonts)
// 獲取指定尺寸的系統(tǒng)標(biāo)準(zhǔn)字體
open class func systemFont(ofSize fontSize: CGFloat) -> UIFont
// 獲取指定尺寸的系統(tǒng)粗體
open class func boldSystemFont(ofSize fontSize: CGFloat) -> UIFont
// 獲取指定尺寸的系統(tǒng)斜體
open class func italicSystemFont(ofSize fontSize: CGFloat) -> UIFont
// 獲取指定尺寸及粗細(xì)程度的系統(tǒng)字體
@available(iOS 8.2, *)
open class func systemFont(ofSize fontSize: CGFloat, weight: CGFloat) -> UIFont
// 獲取指定尺寸及存息程度的等寬數(shù)字系統(tǒng)字體
@available(iOS 9.0, *)
open class func monospacedDigitSystemFont(ofSize fontSize: CGFloat, weight: CGFloat) -> UIFont
不再贅述, 測(cè)試代碼如下:
func testGetSystemFont() {
self.addFontLabelWithFont(font: UIFont.systemFont(ofSize: 18));
self.addFontLabelWithFont(font: UIFont.boldSystemFont(ofSize: 18));
self.addFontLabelWithFont(font: UIFont.italicSystemFont(ofSize: 18));
self.addFontLabelWithFont(font: UIFont.systemFont(ofSize: 18, weight: 3));
self.addFontLabelWithFont(font: UIFont.monospacedDigitSystemFont(ofSize: 18, weight: 3));
}
// MARK: 測(cè)試獲取系統(tǒng)字體
func addFontLabelWithFont(font: UIFont) {
let label = UILabel.init(frame: CGRect.init(x: 40, y: 80 + self.textStyleIndex * 40, width: 400, height: 20));
label.text = font.fontName;
label.font = font;
self.view.addSubview(label);
self.textStyleIndex += 1;
}
結(jié)果如下:
由圖可知万搔,當(dāng)前的默認(rèn)系統(tǒng)字體與monospacedDigitSystemFont
獲取到的字體是一樣的胡桨。
三官帘、獲取可用的字體名稱
// 系統(tǒng)上可用的字體系列的名稱數(shù)組
open class var familyNames: [String] { get }
// 特定字體系列中可用的字體名稱數(shù)組。
open class func fontNames(forFamilyName familyName: String) -> [String]
見名知意昧谊,測(cè)試代碼如下(打印系統(tǒng)直郵的所有字體):
func getAllSystemFonts() {
UIFont.familyNames.map {
UIFont.fontNames(forFamilyName: $0);
}.forEach { (fonts:[String]) in
fonts.forEach({
print($0);
})
};
}
測(cè)試結(jié)果如下:
Copperplate-Light
Copperplate
Copperplate-Bold
KohinoorTelugu-Regular
KohinoorTelugu-Medium
KohinoorTelugu-Light
Thonburi
Thonburi-Bold
Thonburi-Light
CourierNewPS-BoldMT
CourierNewPS-ItalicMT
CourierNewPSMT
......(后續(xù)太多刽虹,不在列舉,可以自己測(cè)試一下)
四揽浙、獲取字體名稱屬性(Getting Font Name Attributes)
// 獲取字體所在的字體系列的名稱
open var familyName: String { get }
// 獲取字體的名稱
open var fontName: String { get }
這兩個(gè)屬性與第三部分一一對(duì)應(yīng)状婶,不再贅述意敛。
五馅巷、獲取字體指標(biāo)(Getting Font Metrics)
// 字體的實(shí)際大小
open var pointSize: CGFloat { get }
// 基準(zhǔn)線以上的高度
open var ascender: CGFloat { get }
// 基準(zhǔn)線以下的高度
open var descender: CGFloat { get }
// 最大文字的高度
open var capHeight: CGFloat { get }
// 小寫字母(x)的高度(相當(dāng)于最小)
open var xHeight: CGFloat { get }
// 行的高度
@available(iOS 4.0, *)
open var lineHeight: CGFloat { get }
// 字體加上下留白的高度
open var leading: CGFloat { get }
對(duì)于這部分沒有概念的話草姻,可以看一下下圖(來自維基百科):
六钓猬、獲取字體描述符
@available(iOS 7.0, *)
open var fontDescriptor: UIFontDescriptor { get }
之前介紹了以下 UIFontDescriptor
, 這里就不再贅述了。
七撩独、完畢
UIFont
這個(gè)類測(cè)試講解到這里就結(jié)束了敞曹,在之后的時(shí)間里,我會(huì)將swift下的UIkit的相關(guān)類依次整理一下综膀,溫故而知新澳迫!感興趣的童鞋,可以關(guān)注我的個(gè)人博客網(wǎng)站http://www.wanglongshuai.com剧劝。