新聞中心
概覽
如果視圖需要數(shù)據(jù)來確定各視圖間共享的單一數(shù)據(jù)源,則可以在視圖最不常見的上級結構中將數(shù)據(jù)存儲為狀態(tài)。既可通過一個 Swift 屬性以只讀方式提供這個數(shù)據(jù),也可使用綁定創(chuàng)建與狀態(tài)的雙向連接。SwiftUI 會觀察數(shù)據(jù)的變化,并根據(jù)需要更新任何受影響的視圖。

讓客戶滿意是我們工作的目標,不斷超越客戶的期望值來自于我們對這個行業(yè)的熱愛。我們立志把好的技術通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領域值得信任、有價值的長期合作伙伴,公司提供的服務項目有:域名與空間、虛擬主機、營銷軟件、網(wǎng)站建設、增城網(wǎng)站維護、網(wǎng)站推廣。
請勿將狀態(tài)屬性用于持久存儲,因為狀態(tài)變量的生命周期與視圖生命周期是一樣的。應將它們用于管理僅影響用戶界面的瞬間狀態(tài),例如按鈕的高亮顯示狀態(tài)、篩選器設置或當前選定的列表項目。你可能還會發(fā)現(xiàn),在你準備對 App 數(shù)據(jù)模型進行更改之前制作原型時,這種存儲很方便。
將可變值作為狀態(tài)來管理
如果視圖需要儲存它可以修改的數(shù)據(jù),應通過 State (英文) 屬性包裝器聲明一個變量。例如,你可以在播客播放器視圖中創(chuàng)建一個 isPlaying Boolean,以跟蹤播客何時運行:
struct PlayerView: View { @State private var isPlaying: Bool = false var body: some View { // ... } }
將屬性標記為狀態(tài)會指示框架管理底層存儲。你的視圖使用屬性名稱,讀取和寫入在狀態(tài)的 wrappedValue (英文) 屬性中找到的數(shù)據(jù)。在你更改值時,SwiftUI 會更新視圖的受影響部分。例如,你可以向 PlayerView 添加一個按鈕,在輕點該按鈕后切換存儲的值并根據(jù)存儲的值顯示不同的圖像:
Button(action: { self.isPlaying.toggle() }) { Image(systemName: isPlaying ? "pause.circle" : "play.circle") }
通過將狀態(tài)變量聲明為私有變量來限制它們的范圍。這確保變量在聲明它們的視圖層次結構中保持封裝狀態(tài)。
聲明 Swift 屬性以存儲不可變值
若要為視圖提供其不修改的數(shù)據(jù),請聲明一個標準 Swift 屬性。例如,你可以擴展播客播放器,以增加一個輸入結構,用于包含代表單集標題和節(jié)目名稱的字符串:
struct PlayerView: View { let episode: Episode // The queued episode. @State private var isPlaying: Bool = false var body: some View { VStack { // Display information about the episode. Text(episode.title) Text(episode.showTitle) Button(action: { self.isPlaying.toggle() }) { Image(systemName: isPlaying ? "pause.circle" : "play.circle") } } } }
盡管單集屬性的值對于 PlayerView 是一個常量,但在這個視圖的父視圖中,它不一定要是常量。當用戶在父項中選擇另一個單集時,SwiftUI 會檢測到狀態(tài)變化并使用一個新輸入來重新創(chuàng)建 PlayerView。
通過綁定共享狀態(tài)訪問
如果視圖需要與一個子視圖共享狀態(tài)的控件,應在帶有 Binding (英文) 屬性包裝器的子項中聲明一個屬性。綁定表示對現(xiàn)有存儲的引用,從而保留底層數(shù)據(jù)的單一數(shù)據(jù)源。例如,如果你將播客播放器視圖的按鈕重構成一個名為 PlayButton 的子視圖,你可以給它提供一個與 isPlaying 屬性的綁定:
struct PlayButton: View { @Binding var isPlaying: Bool var body: some View { Button(action: { self.isPlaying.toggle() }) { Image(systemName: isPlaying ? "pause.circle" : "play.circle") } } }
如上所示,你可以通過直接引用屬性來讀取和寫入綁定包裝的值,這一點與狀態(tài)屬性一樣。但是與狀態(tài)屬性不同的是,綁定沒有自己的存儲,而是引用一個存儲在其他地方的狀態(tài)屬性,并提供與該存儲的雙向連接。
當你實例化 PlayButton 時,可通過添加一個美元符號 ($) 前綴,提供與父視圖中聲明的相應狀態(tài)變量的綁定:
struct PlayerView: View { var episode: Episode @State private var isPlaying: Bool = false var body: some View { VStack { Text(episode.title) Text(episode.showTitle) PlayButton(isPlaying: $isPlaying) // Pass a binding. } } }
$ 前綴要求為它的 projectedValue (英文) 提供一個包裝的屬性,這對狀態(tài)而言,就是與底層存儲的綁定。同樣,你可以通過使用 $ 前綴的綁定獲得綁定,從而讓你可以在視圖層次結構的任意數(shù)量層級間傳遞綁定。
你還可以獲得與狀態(tài)變量中限定范圍的值的綁定。例如,如果你在播放器的父視圖中將 episode 聲明為狀態(tài)變量,并且單集結構還包含一個你想要通過切換控制的 isFavorite Boolean,那么,你可以引用 $episode.isFavorite 來獲得與單集的個人收藏狀態(tài)的綁定:
struct Podcaster: View { @State private var episode = Episode(title: "Some Episode", showTitle: "Great Show", isFavorite: false) var body: some View { VStack { Toggle("Favorite", isOn: $episode.isFavorite) // Bind to the Boolean. PlayerView(episode: episode) } } }
為狀態(tài)過渡添加動畫效果
當視圖狀態(tài)發(fā)生改變時,SwiftUI 會立即更新受影響的視圖。如果你需要實現(xiàn)順暢的視覺過渡,可以將觸發(fā)過渡的狀態(tài)更改包裝在對 withAnimation(_:_:) (英文) 函數(shù)的調用中,以指示 SwiftUI 為它們添加動畫效果。例如,你可以為由 isPlaying Boolean 控制的更改添加動畫效果:
withAnimation(.easeInOut(duration: 1)) { self.isPlaying.toggle() }
通過更改動畫函數(shù)結尾閉包中的 isPlaying,可指示 SwiftUI 為依賴于包裝值的一切內容添加動畫效果,例如,按鈕圖像上的縮放特效:
Image(systemName: isPlaying ? "pause.circle" : "play.circle") .scaleEffect(isPlaying ? 1 : 1.5)
SwiftUI 會使用你指定的曲線和持續(xù)時間,如果你未提供則使用合理的默認值,在一段時間內在給定的 1 和 1.5 值之間過渡縮放特效輸入。另一方面,圖像內容不會受到動畫的影響,即使同一個 Boolean 規(guī)定要顯示哪個系統(tǒng)圖像也是如此。那是因為 SwiftUI 無法以有意義的方式在兩個字符串 pause.circle 和 play.circle 之間逐步過渡。
你可以向狀態(tài)屬性添加動畫,或與上述示例一樣,向綁定添加動畫。無論是哪一種方式,在底層存儲的值發(fā)生變化時,SwiftUI 都會為發(fā)生的任何視圖變化添加動畫效果。例如,如果你在動畫塊位置上方的某個視圖層次結構層級向 PlayerView 添加背景色,SwiftUI 同樣會為此添加動畫效果:
VStack { Text(episode.title) Text(episode.showTitle) PlayButton(isPlaying: $isPlaying) } .background(isPlaying ? Color.green : Color.red) // Transitions with animation.
如果你想將動畫應用于特定的視圖,而不是狀態(tài)變化觸發(fā)的所有視圖,請改用 animation(_:) (英文) 視圖修飾符。
分享名稱:創(chuàng)新互聯(lián)IOS教程:管理用戶界面狀態(tài)
本文網(wǎng)址:http://www.dlmjj.cn/article/dpdpdps.html


咨詢
建站咨詢
