在教程的一開始,我們就說過 SwiftUI 是跨平台的,本文主要講解當開發好基于 iOS 的 App 以後,如何快速實作 watchOS 和 macOS 的跨平台 App。
建立watchOS App
- 給目前項目添加 watchOS 的 Target,選擇 Xcode 菜單:
。File > New > Target > watchOS > Watch App for iOS App
- 和 iOS 一樣,填寫
等資訊。Product Name、Language 和 User Interface
- 在彈出的對話框選擇
。Activate
- 找到建立的 Target,然後點選 General 頁籤,選擇
複選框。Supports Running Without iOS App Installation
- 複制 iOS 項目中的檔案到
中,這裡面有個項目名-Extension
檔案。ContentView.swift
- 編譯程式,由于并不是所有的 View 都是通用的,是以一般會報錯,根據錯誤修改。
- 根據目前裝置的尺寸與分辨率,調整 App 的 UI 進行适配。
- 修改完成以後,在運作按鈕上,可供選擇的 Target 就有了剛剛建立 watchOS App,然後選擇一個模拟器(或真機)運作即可。
建立macOS App
- 給目前項目添加 macOS 的 Target,選擇 Xcode 菜單:
。File > New > Target > macOS > App
- 和 iOS 一樣,填寫
等資訊。Product Name、Language 和 User Interface
- 找到建立的 Target,然後點選 General 頁籤,根據開發的應用程式依賴的 macOS 版本特性,修改
。Deployment Target
- 複制 iOS 項目中的檔案到該項目中,macOS 的項目目錄與 iOS 的幾乎一樣。
- 編譯程式,由于并不是所有的 View 都是通用的,是以一般會報錯,根據錯誤修改。
- 根據目前裝置的尺寸與分辨率,調整 App 的 UI 進行适配。
- 修改完成以後,在運作按鈕上,可供選擇的 Target 就有了剛剛建立 macOS App,然後直接運作,該 App 就會直接運作到目前的電腦上。
案例
以前面提過的天氣預報清單為例來看看 SwiftUI 如何實作跨平台 App 開發。
iOS
代碼
struct ContentView : View {
let titles = ["2019.10.21", "2019.10.22","2019.10.23","2019.10.24","2019.10.25","2019.10.26","2019.10.27"]
let subtitles = ["星期一", "星期二","星期三","星期四","星期五","星期六","星期日"]
let details = ["下雨", "晴天","有霧","多雲","陰天","下雪","大風"]
var body: some View {
List(0..<self.titles.count) { item in
HStack {
VStack {
Text(self.titles[item])
.foregroundColor(.orange)
.bold()
.font(.system(.title))
Text(self.subtitles[item])
.foregroundColor(.gray)
.font(.system(.title))
}.padding(.trailing, 50)
Text(self.details[item])
.foregroundColor(.blue)
.font(.system(.largeTitle))
.italic()
}.padding()
}
}
}
複制
實作效果

iPhone.png
watchOS
如果直接運作 iOS 的代碼,雖然不報錯但 UI 會顯示很難看,是以需要調整一下。
代碼
struct ContentView : View {
let titles = ["2019.10.21", "2019.10.22","2019.10.23","2019.10.24","2019.10.25","2019.10.26","2019.10.27"]
let subtitles = ["星期一", "星期二","星期三","星期四","星期五","星期六","星期日"]
let details = ["下雨", "晴天","有霧","多雲","陰天","下雪","大風"]
var body: some View {
List(0..<self.titles.count) { item in
HStack {
VStack {
Text(self.titles[item])
.foregroundColor(.orange)
.bold()
.font(.system(.title))
Text(self.subtitles[item])
.foregroundColor(.gray)
.font(.system(.subheadline)) // 修改字型大小
}.padding(.trailing, 5) // 修改邊距
Text(self.details[item])
.foregroundColor(.blue)
.font(.system(.largeTitle))
.italic()
}.padding()
}
}
}
複制
實作效果
watchOS.gif
macOS
如果直接運作 iOS 的代碼,雖然不報錯但浪費了很多空間,因為預設視窗的大小為
width: 480, height: 300
,是以需要調整一下。
代碼
struct ContentView : View {
let titles = ["2019.10.21", "2019.10.22","2019.10.23","2019.10.24","2019.10.25","2019.10.26","2019.10.27"]
let subtitles = ["星期一", "星期二","星期三","星期四","星期五","星期六","星期日"]
let details = ["下雨", "晴天","有霧","多雲","陰天","下雪","大風"]
var body: some View {
List(0..<self.titles.count) { item in
HStack() { // 全部橫向顯示
Text(self.titles[item])
.foregroundColor(.orange)
.bold()
.font(.system(size: 30)) // 調整字型
.frame(minWidth: 180, maxWidth: 200) // 設定frame
Text(self.subtitles[item])
.foregroundColor(.gray)
.font(.system(size: 20)) // 調整字型
.frame(minWidth: 80).padding() // 設定frame
Text(self.details[item])
.foregroundColor(.blue)
.font(.system(.largeTitle))
.italic()
.frame(minWidth: 50, maxWidth: 200) // 設定frame
}.padding()
}
}
}
複制
實作效果
macOS.gif