本文為 Eul 樣章,如果您喜歡,請移步 AppStore/Eul 查看更多內容,
Eul 是一款 SwiftUI & Combine 教程 App(iOS、macOS),以文章(文字、圖片、代碼)配合真機示例(Xcode 12+、iOS 14+,macOS 11+)的形式呈現給讀者,筆者意在盡可能使用簡潔明了的語言闡述 SwiftUI & Combine 相關的知識,使讀者能快速掌握并在 iOS 開發中實踐,
常用屬性包裝器
SwiftUI 提供了許多的屬性包裝器(Property Wrapper),極大簡化了我們的作業,屬性包裝器,實際上是對宣告的屬性做了一層封裝,在內部實作了一些我們看不見的操作,
下面會在概念和使用上簡介 SwiftUI 中常用的屬性包裝器,不在代碼層面做具體演示,更詳細的內容可以參見我的兩篇文章:
- SwiftUI-中常見的屬性包裝器(Property-Wrapper)概覽
- SwiftUI(iOS-14)新增屬性包裝器(Property-Wrapper)
@State
在當前 View 中宣告,通常使用 private 修飾,當修飾的屬性值改變時,界面會隨之更新,
@Binding
接收從外部物件傳入的系結值,同時可以將屬性的變化回傳給外部物件,即資料是雙向系結的,如 A 的屬性 @State private var value: String 傳入 B 的屬性 @Binding var value: String ,當 B 中的 value 值改變時, A 的 value 也會更新,
@Environment
訪問預設的環境變數,如系統的暗黑模式、時區等,
@ObservedObject、@Published
@ObservedObject 可以修飾遵循 ObservableObject 協議的 class 物件,該物件實體中的屬性可以使用 @Published 修飾,當使用 @Published 修飾的屬性值發生改變時,所有使用 @ObservedObject 修飾的物件實體,都會更新相應的值,通常用于在多個界面之間同步資料和狀態,
@StateObject
與 @ObservedObject 一樣,@StateObject 修飾的物件同樣是遵循 ObservableObject 協議的 class 物件,但是區別在于,@StateObject 修飾的物件只會在所屬的 View 中創建一次并在 View 的生命周期記憶體儲相應的狀態,而 @ObservedObject 修飾的物件會隨著 View 的重繪生成新的物件,不會在 View 的生命周期記憶體儲該物件的狀態,
@EnvironmentObject
@EnvironmentObject 修飾的物件同樣需要遵循 ObservableObject 協議,與 @ObservedObject 功能類似,但是它有著更強大的功能,子視圖可以直接獲取父視圖注入的環境變數,比如,我們有視圖 A、B、C,A 包含 B,B 包含 C,如果我們使用 @ObservedObject 來傳遞變數,需要從 A 傳入 B,再從 B 傳入 C,C 才能獲取到對應的變數,而 @EnvironmentObject 無需如此繁瑣,我們直接通過父視圖 A 注入環境變數,視圖 C 就可以獲取注入的變數,省去中間的傳遞程序,
@AppStorage
等同于 Userdefaults,
@SceneStorage
用于多視窗模式,相當于為每個場景持久化了一個場景值,每個場景只能讀取該場景持久化的值,當場景銷毀時,該值也會銷毀,建議存盤輕量的、不敏感的資料
@UIApplicationDelegateAdaptor
用來呼叫 AppDelegate 中的生命周期方法,
自定義屬性包裝器
使用屬性包裝器可以使我們的代碼精簡,那么如何根據需求自定義呢?
自定義的屬性包裝器需要使用 @propertyWrapper 宣告,并且必須有一個名為 wrappedValue 的屬性,例如下面的代碼,通過 CNNumber 這樣一個屬性包裝器,可以將字串中的阿拉伯數字轉化成中文數字:
@propertyWrapper
struct CNNumber {
private let table = [
"0" : "〇",
"1" : "一",
"2" : "二",
"3" : "三",
"4" : "四",
"5" : "五",
"6" : "六",
"7" : "七",
"8" : "八",
"9" : "九",
]
private var valuehttps://www.cnblogs.com/bruce2077/archive/2021/05/26/= ""
var wrappedValue: String {
get { value }
set { value = https://www.cnblogs.com/bruce2077/archive/2021/05/26/convertToCNNumbers(newValue) }
}
init(wrappedValue: String) {
self.wrappedValue = wrappedValue
}
func convertToCNNumbers(_ string: String) -> String {
var res =""
for v in string {
res += table[String(v)] ?? ""
}
return res
}
}
然后我們定義一個 Person 結構體,使用 CNNumber 去修飾 birth 屬性,呼叫時正如示例所示,它被轉換成了中文數字,
struct Person {
var name: String
@CNNumber var birth: String
}
struct ContentView: View {
private let p = Person(name: "Steve Jobs", birth: "1955年2月24日")
var body: some View {
Text(p.birth)
}
}
本文為 Eul 樣章,如果您喜歡,請移步 AppStore/Eul 查看更多內容,
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/286160.html
標籤:其他
上一篇:有關Git基礎操作的學習
下一篇:Swift系列九 - 屬性
