SwiftUI 已經(jīng)如同前端vue脏毯、react 一般支持響應(yīng)式編程。也有類似前端的
state
幔崖。如今swiftUI已經(jīng)到2.0版本食店。swift 也已經(jīng)5.5了 。所以現(xiàn)階段從OC 切換到swift是一個非常合適的時機(有點晚)赏寇。了解swift 或者前端就會明白OC的笨重吉嫩。作為一個已經(jīng)使用了8年OC的開發(fā)來說,切換到swift無疑有著不舍嗅定。不過學(xué)習(xí)新的東西自娩,總是充滿了挑戰(zhàn)。
通過最近的學(xué)習(xí)和使用特此整理渠退。本文以實際使用出發(fā)忙迁。具體實現(xiàn)原理待后面研究源碼再進行整理。
在實際項目中使用到的有:
- AppStorage
- Environment
- EnvironmentObject
- ObservedObject
- StateObject
Environment
值類型智什,當(dāng)創(chuàng)建應(yīng)用時动漾,會自動創(chuàng)建Environment。其主要作用是傳遞系統(tǒng)的一些設(shè)置荠锭。如ColorScheme旱眯、NSManagedObjectContext。系統(tǒng)又很多對應(yīng)的key可以查看EnvironmentValues獲取key列表。
在需要使用的view中删豺,只需要使用PropertyWrapper屬性包裝器 @Enviroment
import SwiftUI
struct HomePageView: View {
// colorScheme values: .light, .dark
@Enviroment(\.colorScheme) var colorScheme
var body: some View {
Text("Hello, World")
.foregroundColor(colorScheme = .light ? .yellow : .blue)
}
}
雖然系統(tǒng)自動創(chuàng)建共虑,不過我們也可以自定義一個EnviromentKey,代碼如下:
import Foundation
import SwiftUI
struct UserInfo {
var userName: String = ""
init(userName: String) {
self.userName = userName
}
}
struct UserInfoKey: EnvironmentKey {
static var defaultValue: UserInfo {
return UserInfo(userName: "lixxx")
}
}
extension EnvironmentValues {
var userInfo: UserInfo {
get { return self[UserInfoKey.self] }
set { self[UserInfoKey] = newValue }
}
}
在使用自定義的Environment時,要手動去注入到根視圖上呀页。并初始化注入對象為其設(shè)置一個值妈拌。
import SwiftUI
struct ContentView: View {
var body: some View {
TabbarPageView()
.environment(\.userInfo, UserInfo(userName: "liqingyu"))
}
}
EnvironmentObject
引用類型,和Environment作用相同蓬蝶,可操作性強尘分,可以使用其為應(yīng)用進行設(shè)置全局變量。共享數(shù)據(jù)于應(yīng)用各個頁面丸氛。
首先創(chuàng)建一個全局對象培愁。因為我們要使用這個對象,并且可能會進行修改缓窜,修改后可能會刷新界面等操作定续。所以我們要觀察這個對象 所以使用ObservableObject 協(xié)議 通過@Published 當(dāng)值發(fā)生變化時通知全局作出響應(yīng)。
import Foundation
class Person:ObservableObject {
@Published var name = ""
}
在根視圖上進行注入禾锤,子視圖將可以進行響應(yīng)
import SwiftUI
struct ContentView: View {
var body: some View {
TabbarPageView()
.environmentObject(Person())
}
}
在需要使用的試圖進行引入操作
import SwiftUI
struct EnvironmentPageView: View {
@EnvironmentObject var person: Person
var body: some View {
VStack{
Text("name: \(person.name)")
}
}
}
編輯操作,Binding值綁定 及 = 屬性設(shè)置都是可以的
import SwiftUI
struct EnvironmentDetailView: View {
@EnvironmentObject var person: Person
var body: some View {
TextField("Person", text: $person.name)
.padding(20)
.navigationBarTitleDisplayMode(.inline)
.onAppear(){
person.name = "liqngyu"
}
}
}