What's new in Foundation
1两踏、Apple 專為 Swift 打造了一個新的字符串類型 AttributedString
2连舍、日期和數(shù)字格式化的改進(jìn)
一、屬性字符串 - AttributedString
在 Foundation 框架面世之時蹲蒲,NSAttributedString 類型便隨之一起推出番甩。而今年,Apple 推出了一個基于現(xiàn)代化的 Swift 語言特性的全新的結(jié)構(gòu)體 - AttributedString届搁。
- 1.1 AttributedString基礎(chǔ)
AttributedString是由字符(Characters)缘薛、區(qū)間(Ranges)、字典(Dictionary)3部分組成卡睦。
通過簡單初始化得到AttributedString結(jié)構(gòu)體宴胧,設(shè)置font,foregroundColor表锻,link等屬性恕齐。
AttributeContainer可以根據(jù)不同的AttributedString設(shè)置不同的屬性。
通過調(diào)用 mergeAttributes 方法瞬逊,將攜帶的屬性應(yīng)用在不同的屬性字符串上显歧。
- 1.2 AttributedString View
訪問AttributedString的組成的三部分,并不是通過訪問AttributedString自身确镊,而是通過View士骤。View由兩部分組成:Characters(字符,用來訪問字符串)骚腥、Runs(用來訪問屬性)敦间。
Characters View
首先通過 characters 取出字符 View
遍歷字符 View,并通過 isPunctuation 篩選出字符 View 集合中為標(biāo)點(diǎn)符號的字符束铭,然后設(shè)置其屬性
Runs View
一個 Run View 包含了一個特定的屬性的起始位置廓块、長度、以及具體的屬性值契沫。
由圖中可以看出 Thank you! Please visit our website. 分別是由"Thank you"带猴、"!"、"Please visit our website"懈万、"." 4部分組成拴清。
-
1.3 AttributedString & Markdown
由上圖可以看到靶病,AttributedString 支持 Markdown 語法
- 1.4 AttributedString 轉(zhuǎn)換操作
從結(jié)構(gòu)體類型轉(zhuǎn)換為類類型
直接將AttribuedString 傳入 NSAttributedString 的構(gòu)造方法中
var attributedString111 = AttributedString("This is a basic string.")
attributedString111.inlinePresentationIntent = .stronglyEmphasized
label.attributedText = NSAttributedString(attributedString111)
序列化和反序列化
因為 AttribuedString 有默認(rèn)的 Codable 實(shí)現(xiàn),這里的 TestAttr 結(jié)構(gòu)體只需要遵循 Codable 協(xié)議即可
二口予、格式化器 - Formatters
通過上面的示例代碼娄周,我們可以看到,原來的我們使用日期格式化器的時候,需要創(chuàng)建一個Formatter沪停,然后傳給Formatter一個日期煤辨,返回一個格式化字符串。iOS15之后木张,有了新的Formatters 語法
2.1 新的 Formatters 語法
在最新的 Formatters API 發(fā)布后众辨,我們無需再手動創(chuàng)建并配置 Formatter,同時舷礼,我們也不需要傳給 Formatter 一個日期對象了鹃彻,我么只需要在日期對象身上調(diào)用 formatted 方法,并指定格式化標(biāo)準(zhǔn)是什么妻献。
上面的新Formatters API 更容易理解蛛株,并且可讀性,可維護(hù)性也更高旋奢。
2.2 日期格式化
let date = Date.now
var formatted = date.formatted()
// 9/30/2021, 3:31 PM
let standardDate = date.formatted(date: .abbreviated, time: .standard)
// Sep 30, 2021, 3:31:07 PM
let onlyDate = date.formatted(date: .numeric, time: .omitted)
// 9/30/2021
let onlyTime = date.formatted(date: .omitted, time: .shortened)
// 3:31 PM
let formatter1 = date.formatted(.dateTime.year().day().month())
// Sep 30, 2021
let formattedWide = date.formatted(.dateTime.year().day().month(.wide))
// September 30, 2021
let formattedWeekday = date.formatted(.dateTime.weekday(.wide))
// Thursday
let logFormat = date.formatted(.iso8601)
// 2021-09-30T07:31:07Z
let fileNameFormat = date.formatted(.iso8601.year().month().day().dateSeparator(.dash))
// 2021-09-30
let later = date + TimeInterval(6000)
let range = (date..<later).formatted()
// 9/30/21, 3:50?–?5:14 PM
let noDate = (date..<later).formatted(date: .omitted, time: .complete)
// 3:50:43 PM GMT+8?–?5:14:03 PM GMT+8
let timeDuration = (date..<later).formatted(.timeDuration)
// 1:23:20
let components = (date..<later).formatted(.components(style: .wide))
// 1 hour, 23 minutes, 20 seconds
let relative = later.formatted(.relative(presentation: .named, unitsStyle: .wide))
// in 1 hour
let array: [String] = [formatted, standardDate, onlyDate, onlyTime, formatter1, formattedWide, formattedWeekday, logFormat, fileNameFormat, range, noDate, timeDuration, components, relative]
var temp = ""
for str in array {
temp += str + "\n"
}
print("temp = \(temp)")
formatLabel.text = temp
新的 Formatters API 的一個重要的目標(biāo)是在于創(chuàng)建正確的格式化時提供盡可能多的編譯時支持泳挥。通過指定 formatted 函數(shù)的參數(shù)然痊,可以獲得不同格式的時間表示方式至朗。代碼通過鏈?zhǔn)秸{(diào)用的方式指明需要展示年月日的信息,最終結(jié)果將會根據(jù)用戶的語言環(huán)境 locale 輸出對應(yīng)的內(nèi)容剧浸。字段的順序并不影響锹引,每個字段都只是告訴格式化器在最終的輸出結(jié)果中應(yīng)該包含什么樣的值。
2.3 數(shù)字格式化
let value = 12345
print("value = \(value.formatted())") // 12,345
let percentValue = 30
print("percentValue = \(percentValue.formatted(.percent))") // 30%
let price = 19
print("price = \(price.formatted(.currency(code: "usd")))") // $19.00
let scientific = 42e9
print("scientific = \(scientific.formatted(.number.notation(.scientific)))") // 4.2E10
let list = [25, 50, 75].formatted(.list(memberStyle: .percent, type: .and))
print("list = \(list)") // 25% 50% 75%
數(shù)字格式化支持各種配置唆香,我們可以配置輸出百分比的字符串嫌变,或者是科學(xué)記數(shù)法格式的字符串,亦或者是輸出貨比格式的內(nèi)容躬它。
總結(jié)
- AttributedString 提供了一個快速的腾啥,易用的并且 Swift 優(yōu)先的接口,進(jìn)而實(shí)現(xiàn)在一個字符串的范圍中添加鍵值對以達(dá)到富文本的效果冯吓。你可以在 SwiftUI 中使用 Text 組件倘待,并在本地化字符串中使用 Markdown 語法。
- 新的格式器 API 將重點(diǎn)放在格式上组贺,簡化了代碼并提高了性能凸舵。
What's new in UIKit
- UIButtonConfiguration
我們也可以單獨(dú)定義 UIButtonConfiguration 實(shí)例,并設(shè)置一些諸如文本失尖、圖片等屬性值啊奄,再使用這個實(shí)例來創(chuàng)建按鈕
var config = UIButton.Configuration.tinted()
config.title = "測試按鈕"
config.image = UIImage(named: "close")
config.imagePlacement = .trailing
// config.showsActivityIndicator = true
let configBtn = UIButton(configuration: config, primaryAction: nil)
另外渐苏,我們還可以設(shè)置按鈕的 configurationUpdateHandler,讓按鈕在狀態(tài)發(fā)生改變時自動去執(zhí)行一些操作
configBtn.configurationUpdateHandler = { btn in
if var config = btn.configuration {
config.image = btn.isHighlighted ? UIImage(named: "close") : UIImage(named: "back")
btn.configuration = config
}
}
config.showsActivityIndicator = true
要調(diào)整按鈕布局也很方便菇夸,只需要修改一些屬性值即可,像 baseBackgroundColor琼富、baseForegroundColor、cornerStyle 和 buttonSize 等等庄新。
- Toggle 按鈕
-
Pop-up 按鈕
- UIMenu