(翻譯) SwiftUI - 理解 State

1.png



本文原創(chuàng)作者為: Martin Lasek
原文鏈接:https://medium.com/flawless-app-stories/swiftui-understanding-state-8afa23fd9f1f


在這個教程中,我們將會深入地去理解 State 的基本原理 -- State 是什么纤壁,為什么它起到很好的作用,還有就是如何使用它捺信。

2.gif



索引

  1. 創(chuàng)建一個SwiftUI項目工程
  2. 新建一個Text和一個Button的 view
  3. 理解 State



開始前的準備

為了能夠使用SwiftUI酌媒,需要升級你的系統(tǒng)到macOS Catalina,還有安裝Xcode 11迄靠。

1. 創(chuàng)建一個新的SwiftUI項目

在Xcode中秒咨, 就跟之前創(chuàng)建iOS項目一樣新建一個項目,選擇 Single View App:

3.png

接下來梨水,在確認新建項目之前要確保 Use SwiftUI 是選中狀態(tài):

4.png

2. 新建一個Text和一個Button的 view

新建完項目之后拭荤,你將會看到3個 .swift文件,但我們只要關注 ContentView.swift這個文件疫诽。在這個文件中舅世,我們會看到一個 Text view,讓我們來添加一個 Button view 在里面吧奇徒。

import SwiftUI
struct ContentView : View {
  var body: some View {
    VStack {
      Text("Hello World")
      Button(
        action: { print("Hey Listen!") },
        label: { Text("Switch") }
      )
    }
  }
}
#if DEBUG
struct ContentView_Previews : PreviewProvider {
  static var previews: some View {
    ContentView()
  }
}
#endif



讓我們來分析這里面的每一行代碼吧〕牵現(xiàn)在 VStack 允許我們在垂直方向進行頁面布局。那和它一起配合使用的 HStack摩钙,你猜到了 -- 它允許我們進行水平方向布局罢低。

你已經能夠感受到 SwiftUI 有多么重點關注在 closures(閉包)和 Views 上了吧。

這個Buttonview創(chuàng)建的時候用了兩個閉包胖笛。我們傳進去的第一個閉包將會在 Button 點擊的時候執(zhí)行网持。第二個閉包讓我們能夠 return 將會在 Button 里面顯示的一個 View。

如果你現(xiàn)在允許你的代碼的話长踊,你應該會看到這樣的效果:

5.png

讓我們來為 Text 定義一些風格功舀,讓它可以讓看起來更好一些:

import SwiftUI
struct ContentView : View {
  var body: some View {
    VStack {
      Text("Hello World")
        .frame(
          width: UIScreen.main.bounds.width,
          height: 50
        )
        .background(Color.blue)
        .foregroundColor(Color.white)
        .padding(10)
      Button(
        action: { print("Hey Listen!") },
        label: { Text("Switch") }
      )
    }
  }
}
#if DEBUG
struct ContentView_Previews : PreviewProvider {
  static var previews: some View {
    ContentView()
  }
}
#endif

如果你覺得這個有些嚇人的話,不用擔心的身弊。這只是我們的一個新功能而已辟汰。就像我們在那時候學會了像這樣去設置UIView的背景顏色:

myView.backgroundColor = .blue

以后我們閉著眼睛都能在SwiftUI中去實現(xiàn)backgroundColor列敲,只是時間問題而已。

運行這些代碼的話帖汞,我們會看到像下面一樣酷的結果:

6.png

3. 理解 State

再看看我們的代碼戴而,其實我們是想傳入一個數(shù)碼寶貝的名字給我們的 Text view。別忘了翩蘸,我們只有一個簡單的 Struct而已所意,沒有其它神奇的東西。我們前面已經使用過了 Struct鹿鳖,并且在它里面定義過屬性和方法扁眯。

所以,讓我們來定義一個 pokemonName的屬性和一個改變它的方法:

import SwiftUI
struct ContentView : View {
  var pokemonName = "Charmander"
  var body: some View {
    VStack {
      Text(pokemonName)
        .frame(
          width: UIScreen.main.bounds.width,
          height: 50
        )
        .background(Color.blue)
        .foregroundColor(Color.white)
        .padding(10)
      Button(
        action: { self.switchPokemon() },
        label: { Text("Switch") }
      )
    }
  }
  func switchPokemon() {
    pokemonName = "Pikachu"
  }
}
#if DEBUG
struct ContentView_Previews : PreviewProvider {
  static var previews: some View {
    ContentView()
  }
}
#endif



Xcode將會報錯: Cannot assign to property: 'self' is inmutable

這是因為 Struct(結構體)默認是不能改變它的屬性的翅帜。它會在 func switchPokemon方法前面報 mutating姻檀。但這不是我們的問題 -- 我們只要在 pokemonName 前面加上 @State 關鍵字就解決這問題了!

這個關鍵字是做什么的涝滴?為什么它這么好用呢绣版?

當 State 更新的時候,view將重新校驗UI歼疮,并且更新自身杂抽。


  • 從原理上說,我們只要改變了 view 里面被關鍵詞 @State 修飾的屬性韩脏,整個 viewbody 就會被重新渲染缩麸。

現(xiàn)在讓我們繼續(xù)運行項目,看看視圖里面的 text 是怎樣切換成 pikachu 吧赡矢!

7.gif

當視圖的 body 第一次渲染出來的時候杭朱,我們是將 “Charmander” 作為 pokemonName 的默認值,而且pokemonName是被 @State 關鍵字修飾的吹散。所以我們運行后第一時間會看到顯示的是 “Charmander”弧械。

當我們點擊 button,文本將會更新為 “Pikachu”, 因為我們更新的是一個 state 屬性的值空民,所以頁面重新渲染了刃唐,所以這次顯示了 “Pikachu”。

我們可以將 pokemonName 改成隨機的界轩,也就是隨機地更新它的值:

import SwiftUI
struct ContentView : View {
  @State var pokemonName = "Charmander"
  var body: some View {
    VStack {
      Text(pokemonName)
        .frame(
          width: UIScreen.main.bounds.width,
          height: 50
        )
        .background(Color.blue)
        .foregroundColor(Color.white)
        .padding(10)
      Button(
        action: { self.switchPokemon() },
        label: { Text("Switch") }
      )
    }
  }
  func switchPokemon() {
    let list = ["Squirtle", "Bulbasaur", "Charmander", "Pikachu"]
    pokemonName = list.randomElement() ?? ""
  }
}
#if DEBUG
struct ContentView_Previews : PreviewProvider {
  static var previews: some View {
    ContentView()
  }
}
#endif

現(xiàn)在画饥,你已經完成了這么一個View:它通過修改被 @State 修飾的屬性,就會重新渲染浊猾。
你現(xiàn)在點擊按鈕荒澡,它應該可以隨機切換更新 pokemon name了。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末与殃,一起剝皮案震驚了整個濱河市单山,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌幅疼,老刑警劉巖米奸,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異爽篷,居然都是意外死亡悴晰,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進店門逐工,熙熙樓的掌柜王于貴愁眉苦臉地迎上來铡溪,“玉大人,你說我怎么就攤上這事泪喊∽亓颍” “怎么了?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵袒啼,是天一觀的道長哈扮。 經常有香客問我,道長蚓再,這世上最難降的妖魔是什么滑肉? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮摘仅,結果婚禮上靶庙,老公的妹妹穿的比我還像新娘。我一直安慰自己娃属,他們只是感情好六荒,可當我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著膳犹,像睡著了一般恬吕。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上须床,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天铐料,我揣著相機與錄音,去河邊找鬼豺旬。 笑死钠惩,一個胖子當著我的面吹牛,可吹牛的內容都是我干的族阅。 我是一名探鬼主播篓跛,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼坦刀!你這毒婦竟也來了愧沟?” 一聲冷哼從身側響起蔬咬,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎沐寺,沒想到半個月后林艘,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡混坞,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年狐援,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片究孕。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡啥酱,死狀恐怖,靈堂內的尸體忽然破棺而出厨诸,到底是詐尸還是另有隱情镶殷,我是刑警寧澤,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布泳猬,位于F島的核電站批钠,受9級特大地震影響,放射性物質發(fā)生泄漏得封。R本人自食惡果不足惜埋心,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望忙上。 院中可真熱鬧拷呆,春花似錦、人聲如沸疫粥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽梗逮。三九已至项秉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間慷彤,已是汗流浹背娄蔼。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留底哗,地道東北人岁诉。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像跋选,于是被迫代替她去往敵國和親涕癣。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,055評論 2 355

推薦閱讀更多精彩內容