新聞中心
概覽
你通常會在你的 App 中,使用與用戶界面和其他邏輯分離的數(shù)據(jù)模型來存儲和處理數(shù)據(jù)。這種分離可促進模塊化、提升可測試性,并更加便于推斷你的 App 的運行方式。

創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供巧家網(wǎng)站建設、巧家做網(wǎng)站、巧家網(wǎng)站設計、巧家網(wǎng)站制作等企業(yè)網(wǎng)站建設、網(wǎng)頁設計與制作、巧家企業(yè)網(wǎng)站模板建站服務,十年巧家做網(wǎng)站經(jīng)驗,不只是建網(wǎng)站,更提供有價值的思路和整體網(wǎng)絡服務。
此前,你使用一個視圖控制器在模型和用戶界面之間來回移動數(shù)據(jù),而此同步過程的大部分工作都可由 SwiftUI 為你處理。若要在數(shù)據(jù)發(fā)生變化時更新視圖,你需要使你的數(shù)據(jù)模型類成為可觀察對象、發(fā)布它們的屬性并使用特殊屬性聲明它們的實例。為確保用戶驅(qū)動的數(shù)據(jù)更改回流到模型中,你需要將用戶界面控件與模型屬性進行綁定。這些功能一起幫助你維護數(shù)據(jù)的單一來源。
將模型數(shù)據(jù)設為可觀察
要讓模型中的數(shù)據(jù)變化對 SwiftUI 可見,請為模型類采用 ObservableObject (英文) 協(xié)議。例如,你可以創(chuàng)建一個 Book 類作為可觀察對象:
class Book: ObservableObject { }
系統(tǒng)會自動推斷該類的 ObjectWillChangePublisher (英文) 關聯(lián)類型,并合成必需的 objectWillChange (英文) 方法來發(fā)出已發(fā)布屬性的更改值。若要發(fā)布屬性,請將 Published (英文) 屬性添加到屬性的聲明:
class Book: ObservableObject { @Published var title = "Great Expectations" }
請避免已發(fā)布屬性的不必要開銷。僅發(fā)布既能更改又對用戶界面很重要的屬性。例如,Book 類可能有一個在初始化后從不更改的 identifier 屬性:
class Book: ObservableObject { @Published var title = "Great Expectations" let identifier = UUID() // A unique identifier that never changes. }
你仍可以在用戶界面中顯示該標識符,但由于它未發(fā)布,SwiftUI 知道不必觀察該特定數(shù)據(jù)的變化情況。
監(jiān)測可觀察對象的變化
若要指示 SwiftUI 監(jiān)測可觀察對象,請將 ObservedObject (英文) 屬性添加到屬性的聲明:
struct BookView: View { @ObservedObject var book: Book var body: some View { Text(book.title) } }
你可以將所觀察對象的各個屬性傳遞到子視圖,如上所示。當數(shù)據(jù)發(fā)生變化時,例如,當你從磁盤載入新數(shù)據(jù)時,SwiftUI 會更新所有受影響的視圖。你還可以將整個可觀察對象傳遞到子視圖,并在視圖層次結構的各個層級之間共享模型對象:
struct BookView: View { @ObservedObject var book: Book var body: some View { BookEditView(book: book) } } struct BookEditView: View { @ObservedObject var book: Book // ... }
實例化視圖中的模型對象
SwiftUI 可能會隨時創(chuàng)建或重新創(chuàng)建一個視圖,因此很重要的一點是:用給定的一組輸入來初始化視圖時,要能夠始終產(chǎn)生相同的視圖。因此,在視圖中創(chuàng)建被觀察對象不是很安全的做法。你應借助 SwiftUI 提供的 StateObject (英文) 屬性來實現(xiàn)這一用途。你可以通過以下方式在視圖中安全地創(chuàng)建一個 Book 實例:
struct LibraryView: View { @StateObject var book = Book() var body: some View { BookView(book: book) } }
狀態(tài)對象的行為就像被觀察對象一樣,唯一不同的是,無論 SwiftUI 重新創(chuàng)建了一個視圖多少次,它都能夠創(chuàng)建并管理給定視圖實例的單一對象實例。你可以在本地使用該對象,或?qū)顟B(tài)對象傳遞到另一個視圖的被觀察對象屬性,如上述示例所示。
盡管 SwiftUI 不會在視圖中重新創(chuàng)建狀態(tài)對象,但它卻會為每個視圖實例創(chuàng)建一個不同的對象實例。例如,以下代碼中的每個 LibraryView 都將獲得一個唯一的 Book 實例:
VStack { LibraryView() LibraryView() }
你還可以在頂層 App (英文) 實例或你 App 的一個 Scene (英文) 實例中創(chuàng)建一個狀態(tài)對象。例如,如果你為一個圖書閱讀器 App 定義一個名為 Library 的可觀察對象來保留一系列圖書,你可以在該 App 的頂層結構中創(chuàng)建一個資料庫實例:
@main struct BookReader: App { @StateObject var library = Library() // ... }
在整個 App 中共享對象
如果你有一個想在整個 App 中使用的數(shù)據(jù)模型對象,但是,你不想將它傳遞到層次結構的多個層級,你可以改用 environmentObject(_:) (英文) 視圖修飾符,將該對象放置在環(huán)境中:
@main struct BookReader: App { @StateObject var library = Library() var body: some Scene { WindowGroup { LibraryView() .environmentObject(library) } } }
然后,應用了該修飾符的視圖的任何子代視圖均可通過使用 EnvironmentObject (英文) 屬性聲明一個屬性來訪問該數(shù)據(jù)模型實例:
struct LibraryView: View { @EnvironmentObject var library: Library // ... }
如果你使用環(huán)境對象,可以將它添加到 App 層次結構頂部的視圖,如上所示。或者,你可以將它添加到視圖層次結構中某個子樹的根視圖。無論采用哪種方式,都還要記得將其添加到使用此對象或子代使用此對象的任何視圖的預覽提供程序:
struct LibraryView_Previews: PreviewProvider { static var previews: some View { LibraryView() .environmentObject(Library()) } }
使用綁定創(chuàng)建雙向連接
如果你允許用戶在用戶界面中更改數(shù)據(jù),請使用與相應屬性的綁定。這確保更新會自動回流到數(shù)據(jù)模型中。你可以通過給對象的名稱添加美元符號 ($) 前綴,獲得與被觀察對象、狀態(tài)對象或環(huán)境對象屬性的綁定。例如,如果你讓用戶通過向 BookEditView 添加一個 TextField (英文) 來編輯某圖書的書名,應為文本欄提供與該圖書的 title 屬性的綁定:
struct BookEditView: View { @ObservedObject var book: Book var body: some View { TextField("Title", text: $book.title) } }
該綁定將視圖元素與底層模型進行關聯(lián),以便用戶可直接更改模型數(shù)據(jù)。
當前題目:創(chuàng)新互聯(lián)IOS教程:在你的App中管理模型數(shù)據(jù)
本文地址:http://m.5511xx.com/article/djhdsep.html


咨詢
建站咨詢
