[Android開發學iOS系列] iOS寫UI的幾種方式

[Android開發學iOS系列] iOS寫UI的幾種方式

作為一個現代化的平台, iOS的發展也經歷了好幾個時代.

本文講講iOS寫UI的幾種主要方式和各自的特點.

iOS寫UI的方式

在iOS中寫UI有多種選擇, 大的分類: 使用UIKit還是SwiftUI.

在使用UIKit的情形下, 還根據是否使用storyboard來區分.

  • UIKit:
    • 用storyboard.也叫Interface Builder.
    • 採用程式碼來寫UI, 手寫約束.
  • SwiftUI.

注意: 以上的幾種方式在項目里可能是混合使用的, 所以建議都了解.

UIKit

UIKit是蘋果官方的framework, 其中包含了UI組件和各種基礎設施支援, 是傳統的iOS開發離不開的一套類庫.
UIViewController就屬於UIKit.

用Storyboard

我們新建的項目, 如果不選SwiftUI, 都會帶一個main storyboard.

用Storyboard寫UI大致分為這幾步:

  • 在Storyboard中添加控制項. 用Cmd + Shift + L可以呼出菜單. 可以添加View或者新的View Controller.
  • 設置屬性, 約束. (側面面板, 右下角約束按鈕, 以及Ctrl+拖拽生成相對約束).
  • 需要有在程式碼中的交互:
    • 顯示Assistant View之後將對應的ViewController類程式碼同時顯示出來.
    • Ctrl + 拖拽 生成outlet(用於控制控制項本身屬性)或者action(控制項的點擊事件).

(這一步也不是必須這樣做, 也可以先手寫出outlet程式碼, 然後拖拽連起來.)

優點:

  • 圖形介面編輯.
  • 可以不用build看到UI預覽效果.

缺點: 因為程式碼是一個xml文件中track, 在團隊合作容易產生不好解決的衝突.

用程式碼寫View和約束(不用Storyboard)

首先, 在loadView()中設置view:

override func viewDidLoad() {
      super.viewDidLoad()
      
      view = UIView()
      view.backgroundColor = .white
}

然後不斷地addSubview()進去.

其中子view可以是controller中聲明的欄位:

var myLabel: UILabel!

這裡加上感嘆號有kotlin中類似lateinit的作用, 否則會提示controller沒有init方法.

之後再添加Constraints.

優點: 都用程式碼寫, 歷史清晰, 衝突好解決.

缺點: 要用程式碼寫約束; 寫起來比較啰嗦; 運行之後才能看到實際的效果.

SwiftUI

SwiftUI是iOS新推出的聲明式的寫UI的方式, 可以類比Android的Jetpack Compose.

新建項目以後的Hello World大概長這樣:

App:

import SwiftUI

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

ContentView:

import SwiftUI

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

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

優點:

  • 最新的技術, 符合未來發展的潮流(類比Compose, Flutter, React Native).
  • 使用方便簡單, 易上手.
  • Xcode的預覽和編輯功能都支援得不錯, 可以在屬性面板上直接添加或者編輯屬性, 有程式碼自動聯動.
  • 可以和UIKit的老程式碼互操作, 兼容良好.

缺點:

  • 要求OS版本13及以上.
  • 因為整體的設計思路變為了functional programming, 所以舊程式碼遷移需要做一些設計方面的思維轉換, 並不是替換了一套UI庫這麼簡單.
  • 如何說服團隊使用.
Tags: