#28 Stanford CS193p — Developing Apps for iOS using SwiftUI —Note of Lecture #1

想利用 6 月到 7 月這個空檔來追一部 on 檔劇,自學一下 SwiftUI 和練習一下英聽,希望不會棄劇 ( orz )。這堂課是由 Stanford 的 Paul Hegarty 教授主講,我把連結放在下方,大家有空也可以一起追劇喔~

Open new project with SwiftUI

SwiftUI 也同樣透過 Xcode 平台來開發,在建立新專案時,打上你的專案名稱後,我們將 Interface 由原本的 Storyboard 改為 SwiftUI。在 Life Cycle 選擇的是 SwiftUI App (第二個選項是 UIKit App Delegate,教授是說這是混合Storyboard and SwiftUI 去開發 APP 的方式),語言的部分以往我們在用 Storyboard 開發時還有 Objective-C 可以選,SwiftUI 只能用 Swift 來撰寫了。

Tour of Xcode

要我說 SwiftUI 最酷的地方,大概就是他的 Previewer 功能吧。之前用 UIBezierPath 畫圖的時候,就體會到 SwiftUI 的美好,可以即時預覽你寫的程式,及時修正,連模擬器都不用開起來呢,連教授都讚譽有加~

還有個地方教授特別提到,就是當你在 Coding 的時候,Xcode 會自動把相關的地方 Link 在一起。例如我在編輯 Hello world 時,Previewer 會自動把 Hello world 選起來,右方的 Inspector 也會 Show 出相關資訊。

Go through line by line

import SwiftUI

教授提到 SwiftUI 還有一個滿棒的地方是,他可以分離設計 UI 介面的 code 和 logic 頁面的 code 。先前在使用 storyboard 來寫 code 的時候,往往我會把所有東西都寫在一個 ViewController 裡面,這裡每個檔案都有它不同的用途,分的乾淨也能夠增加易讀性與 debug 的方便性。

struct ContentView: View {var body: some View {Text("Hello, world!")}}

struct : 是 data structure 的英文縮寫,collections of variables,但在 Swift 裡面的 struct 是可以加入 func 的。

ContentView : 就是我們為這個 struct 命的名字。

View : 接在你命名後面的 View ,意思就是你的這個 struct 擁有 View 的特性,也就是說 View 可以有的功能,這個 struct 都可以擁有。

var : Variables ,變數。

body : 緊接在 var 後方的就是變數的名字。

some view : 這邊教授花了一小段篇幅在講為什麼我們定義了這個 struct 擁有 View 的特性後,我們還要定義一個變數讓它擁有 View 的特性。

其實教授講的滿好的,翻譯成中文大概就是我們在做一個 App 的時候就像在玩樂高蓋房子一樣,房子裡面會有很多功能性空間像是臥房、廚房、客廳。而每個房間裡面又有很多小東西,例如廚房裡面可能有餐桌或是椅子。

當你在蓋樂高房子裡的廚房的時候你可以不用規劃不用分類,需要蓋什麼就從頭開始思考怎麼蓋,然後把東西蓋出來。

但其實有更有效率的方式,就是模組化。例如廚房裡面有八張一模一樣的椅子,當你蓋好第一個椅子,你可以給這個椅子命名成樂高椅子,剩下的七張椅子全部按照這個設計藍圖蓋好就好。

這就是為什麼我在 struct 裡面還要特別定義一個變數讓他擁有 View 的特性。

Text(“Hello, world!”) : 這個就像是最小碎片的樂高了

整段看完之後,不知道你是不是有跟我一樣的疑問,那 some 呢?為什麼 view 前面會有 some ?整段影片我看了兩次才大概理解。以往我們在定義變數時,冒號後面會接 Int 或 String…等等來描述這個變數的屬性。多了一個 Some 可以把它理解成 Some of ,你可以把這段程式翻譯成 “這個 body 是 View 的某些屬性”

所以我們以這段程式為例的話,其實我們可以不用寫 some View,我們改成 var body: Text 一樣跑的起來。

那為何這麼麻煩還要寫個 some View ?

我們嘗試約束這個文字,把右邊的 Padding 勾選起來會發現出現紅色警告,說 “Cannot convert value of type ‘some View’ to specified type ‘Text’” 。

有發現為什麼了嗎?因為 Padding 不是 Text 所擁有的特性,當我們定義這個變數是 Text ,但裡面的內容卻有不是 Text 特性的東西時,就會出錯。所以我們可以把變數的屬性定義再擴大,變成 some View,這樣裡面就可以同時裝 Text or Padding…等等。

Get started to design your App

課堂上會以 Card game — Concentration 當作例子,在大概講完上面的觀念後就會開始實作來設計卡片了。

還有一點教授特別提到的是,當你在右方找不到你想變更設計的工具時,可以在下方搜尋列打上關鍵字去尋找喔。

再來講到一個特別的東西叫做 ZStack ,用樂高來比喻的話就像是,如果我們去買星際大戰的樂高,貼心的樂高公司已經幫你分裝好例如武器包或是建築物包了,這種一包一包的概念就是 ZStack。

所以我們可以把剛剛設計的卡片以及文字都放在這包 ZStack 裏面

當然,如果你不想要他們置中的話也可以,可以在 Zstack 裡面加上 alignment 去改變位置。

這裡還提到一個小技巧,如果我們把這些屬性搬到外層去針對 Zstack 做改變的話,那 Zstack 裡面所有元素都會被改變到,就像上圖我把 .foregroundColorpadding 搬到外層,裡面的 RoundedRectangleText 都會被改變到。

Clean up your code

影片最後提到,其實 Swift 很聰明,他知道開發者在某些時候要做某些動作,所以其實很多地方是可以省略,讓你的程式看起來更乾淨:

  1. 在 foregroundColor 裡面設定顏色時,其實正確是要打 color.red ,但當你叫出 foregroundColor 時,Swift 就知道你要設定顏色了,所以直接打 .red 也是 OK 的。
  2. ZStack 前面的 Return 也可以省略,因為這是一個 function ( some View 後面有對 {} ),我們知道他會回傳 View 裡面的某些東西。
  3. 若你原本就要置中的話, alignment: .center 也可以刪掉,因為預設就是中間。
  4. ZStack 裡面,第一行最後的 content ,他的值代表著一段 func ,如果你打開快速查閱工具可以看到他的註解是 “A view builder that creates the content of this stack” ,代表凡是我們創造一個 ZStack,基本上就是要創造一段內容來包在這個 ZStack 裡面,這個 content: 也可以省略。(這種可以省略的通常會放在最後一個,也就是大跨號前面)

所以整段 code 就會被整理成如下。

到這裡就是第一堂課 80 分鐘的筆記囉~

Free talk

其實教授講的不無聊,會用很多貼近生活的例子來去解釋。只是很多時候還是得暫停下來,練習操作和筆記,剛好利用空閒的六月來學學新東西順便練練英聽吧~

--

--