初探 SwiftUI (2)
繼上次的清單點選到詳細頁後(Navigation),接下來要加上一些使用者操作對應的 UI 切換。
將每個電影細項加上 “最愛” 標記,使用者可以透過開關選項來決定是否只顯示出 “最愛” 的項目。
獨立 List Row UI 與加上 “最愛” 屬性 (星星符號)
先將清單中欄位的 UI 單獨切出,新增 ListRowView.swift 並加上 SF Symbol 表示是否是 “最愛” 項目。
加入開關 與 View 的狀態
當 var body: some View
裡的畫面對應某個參數,依據給予的參數不同而產生對應的畫面時,需要將參數前面加上@State。當參數改變時,SwiftUI 會刷新整個 Content View。
@State為一個 View 的狀態屬性,包含一個值或者一組值的集合,標記這個結構體的參數是可變的,它將會影響 View 的行為、內容或者是排版。
View 要與狀態屬性關聯在一起(binding),需加入 “$” 前綴符號,這樣一但 @State 的狀態發生改變,View 會自動刷新,但需注意只能在var body: some View
裡使用 @State 參數。
將此狀態與開關的 On/Off 連結在一起。
使用 Observable Object 儲存使用者標記最愛
Observable Object 使用 Combine 框架,Observable Object 客製化物件可將資料與畫面綁在一起,並且可被 SwiftUI 環境儲存。
當 Object 變動時會自動廣播,SwiftUI 可訂閱此物件,當物件有改動時 SwiftUI 刷新 var body: some View
,進而更新畫面。
參數加上 @Published
即可讓 SwiftUI 訂閱,此屬性為可選值。
詳細頁新增能夠得知陣列 index 的屬性
新增可知道全部電影清單的觀察屬性,利用比對得到上個畫面傳入單一電影資料在全部清單中的位置。
在詳細頁加上 “加入最愛” 的互動按鈕
執行 Simulator 時出現 Fatal error: No ObservableObject of type UserData found.
若使用 App Delegate,在增加 @EnvironmentObject 後除了在 Preview Provider 加上View().environmentObject(:)
之外,也需要至 App Delegate 修正UIHostingController(rootView:)
。
若使用 SwiftUI App,則須至<AppName>App.swift 內做相同修正。