SwiftUI 數據狀態和綁定
標簽: SwiftUI 入門 ios swift swiftui
SwiftUI 數據狀態和綁定
方案 | 說明 | 備注 |
---|---|---|
@State & @Binding | 提供 View 內部的狀態存儲 | 應該是被標記為 private 的簡單值類型,僅在內部使用。 |
ObservableObject & @ObservedObject | 針對跨越 View 層級的狀態共享 | 處理更復雜的數據類型,在數據變化時觸發界面刷新。 |
@EnvironmentObject | 對于 “跳躍式” 跨越多個 View 層級的狀態 | 更方便地使用 ObservableObject,以簡化代碼。 |
@State
& @Binding
Parent view:
struct ParentView: View {
@State private var foo: Bool = false
var body: some View {
VStack(spacing: 25) {
Text("foo in Parent: \(self.foo ? "?" : "")")
ChildView(foo: $foo)
}
}
}
Child view:
struct ChildView: View {
@Binding var foo: Bool
var body: some View {
Button("toggle foo from Child") {
self.foo.toggle()
}
}
}
運行效果:
@ObservedObject
Model:
class Model: ObservableObject {
@Published var foo: Bool = false
}
注意,@Published
是個 internal 的。在 Xcode 工程里沒事,但在 Playground 的 Sources 里寫是必須 public 的,這時可以采用下面這種手動處理的方法:
import Combine
public class Model: ObservableObject {
public let objectWillChange = PassthroughSubject<Void, Never>()
public var foo: Bool = false {
willSet { objectWillChange.send() }
}
public init() {}
}
let objectWillChange = PassthroughSubject<Void, Never>()
用來實現ObservableObject
協議;- 給每個需要
@Published
的變量加willSet { objectWillChange.send() }
。
Parent View:
public struct ParentView: View {
@ObservedObject var model: Model = Model()
public var body: some View {
VStack(spacing: 25) {
Text("foo in Parent: \(self.model.foo ? "?" : "")")
ChildView(model: model)
}
}
public init() {}
}
Child View:
public struct ChildView: View {
var model: Model
public var body: some View {
Button("toggle foo from Child") {
self.model.foo.toggle()
}
}
public init(model: Model) {
self.model = model
}
}
這里其實是利用 class 的“傳引用”特性來讓子訪問到父的 model 的,沒什么特殊的。
@EnvironmentObject
沿用上面 ObservableObject
的 Model:
class Model: ObservableObject {
@Published var foo: Bool = false
}
Parent View:
public struct ParentView: View {
@EnvironmentObject var model: Model
public var body: some View {
VStack(spacing: 25) {
Text("foo in Parent: \(self.model.foo ? "?" : "")")
ChildView()
}
}
public init() {}
}
Child View:
public struct ChildView: View {
@EnvironmentObject var model: Model
public var body: some View {
Button("toggle foo from Child") {
self.model.foo.toggle()
}
}
public init() {}
}
調用 Parent 的 View:
ParentView().environmentObject(Model())
用 EnvironmentObject 讓所有子都訪問到父的 Model,可以避免逐層手動傳遞對象。
完整源碼實現:SwiftUIDataStateAndBinding.playground。
參考
王巍 (@onevcat)《SwiftUI 與 Combine 編程》Chapter 3:數據狀態和綁定
智能推薦
SwiftUI 超強大文章編輯組件支持多行顯示并限制行數與字符數(兼容SwiftUI1.0和SwiftUI 2.0)
SwiftUI 超強大文章編輯組件支持多行顯示并限制行數與字符數(兼容SwiftUI1.0和SwiftUI 2.0) 實戰需求 SwiftUI的TextField和TextEditor目前都存在中文輸入問題, 如何優雅的隱藏鍵盤也是個問題? 如何獲取字符數和行數呢? 如何限制字符數和行數呢? 本文將為大家制作個可以用于生產環境的強大文本輸入框 本文價值與收獲 看完本文后,您將能夠作出下面的界面 看...
SwiftUI實戰三:創建List視圖和導航Navigation
系統: Mac OS 10.15.1, XCode 11.2.1,swift 5.0 寫作時間:2019-11-30 1. 說明 此例子包含元素:List視圖(代替以前的TableView), 導航。這個例子接著上一個例子SwiftUI實戰二:組合視圖和地圖視圖,把它當作詳情頁。 細節請查看官網教程 2. 元素以及代碼下載 https://github.com/zgpeace/BuildingLi...
SwiftUI-HStack、VStack和ZStack組合用
文章目錄 前言 效果圖 代碼 前言 個人學習 SwiftUI 的記錄,如有錯誤,請指教哈! 效果圖 這里展示了, 組合用幾個布局寫一個卡片 ( 好吧,好像好多文章都是寫卡片 ) 先上效果圖 代碼...
SwiftUI實戰二:組合視圖和地圖視圖
系統: Mac OS 10.15.1, XCode 11.2.1,swift 5.0 寫作時間:2019-11-29 說明 此例子包含元素:縱向組合容器VStack, 橫向組合容器HStack,UIImage,Map。這個項目的表達的意思是,地圖給出一個經緯度地標,顯示圖文介紹。 細節請查看官網教程 創建工程 工程名字:CreatingAndCombiningViews User Interfac...
SwiftUI JSON文件下載、存儲、解析和展示(代碼大全)
JSON 簡介 JSON(JavaScript Object Notation, JS 對象簡譜) 是一種輕量級的數據交換格式。它基于 ECMAScript (歐洲計算機協會制定的js規范)的一個子集,采用完全獨立于編程語言的文本格式來存儲和表示數據。簡潔和清晰的層次結構使得 JSON 成為理想的數據交換語言。 易于人閱讀和編寫,同時也易于機器解析和生成,并有效地提升網絡傳輸效率。 我們通常從服務...
猜你喜歡
SwiftUI 基礎之05 list 和 searchbar (2020)
SwiftUI 基礎之05 list 和 searchbar (2020) 首要 searchbar 效果圖 image.png 參考資料 https://medium.com/better-programming/implement-searchbar-in-swiftui-556a204e1970...
freemarker + ItextRender 根據模板生成PDF文件
1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...
電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!
Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...
requests實現全自動PPT模板
http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...