請 AI 一步一步慢慢教,帶著初學者開發 iOS App — 以 10YearChallenge App 為例
--
彼得潘出了超過 200 道的 iOS App 作業,因此上課的同學們每天都可以開心地寫作業。
不過如果遇到以下三種情況,倒是可以考慮請聰明善良耐心的 AI 老師幫忙。
- 作業想破頭寫不出來。
- 已經完成作業,想請 AI 改作業。
- 已經完成作業,想了解其它寫法。
ChatGPT,Notion AI & Cursor 都是不錯的 AI 老師。Cursor 目前串接 GPT-4,因此寫程式的功力還不錯。以下彼得潘以 10YearChallenge 為例,請 Cursor 一步一步慢慢教,帶著身為初學者的我們開發 iOS App。
- 安裝 Cursor App。
- 打開 Cursor App,按 cmd + l 輸入問題。
請一步一步慢慢教,列出一連串的步驟,教我用 storyboard,IBOutlet & IBAction 做出 10YearChallenge App。
10YearChallenge App 的功能如下。
1. 使用 date picker 選時間,顯示自己 2014 ~ 2023 的變化成長,一年一張照片。
2. date picker 設定最小 & 最大時間,讓時間的範圍為 2014 ~ 2023。
3. 使用 slider 選時間,顯示自己 2014 ~ 2023 的變化成長,一年一張照片。
4. slider 設定最小值為 2014,最大值為 2023。
5. slider 的旁邊有個 label 顯示年份。
6. 滑動 slider 時,slider 會停在整數的位置,比方滑到 2020.6 時會四捨五入到 2021。
7. 當 slider 滑動時,date picker 會更新。比方 slider 滑到 2020,date picker 會選到 2020。
8. 當 date picker 選時間時,slider 會更新。比方 date picker 選到 2020,slider 會滑到 2020。
ps: AI 回答到一半中斷時,請輸入 Continue writing
請它繼續寫。
以下為 AI 的回答。
使用 storyboard 建立 UI
- 在 Xcode 中建立新的 project,選擇 Single View App。
- 在左側的專案導覽欄中,點擊 Main.storyboard。
- 在右側的工具欄中,選擇 Date Picker,拖曳到畫面中央。
- 在右側的工具欄中,選擇 Image View,拖曳到畫面中央。
- 在右側的工具欄中,選擇 Slider,拖曳到畫面下方。
- 在右側的工具欄中,選擇 Label,拖曳到 Slider 的旁邊。
設定 Date Picker
- 選擇 Date Picker,點擊右側的 Attributes inspector。
- 設定 Date Picker 的 Mode 為 Date。
- 設定 Date Picker 的 Minimum Date 為 2014 年 1 月 1 日。
- 設定 Date Picker 的 Maximum Date 為 2023 年 12 月 31 日。
設定 Slider
- 選擇 Slider,點擊右側的 Attributes inspector。
- 設定 Slider 的 Minimum Value 為 2014。
- 設定 Slider 的 Maximum Value 為 2023。
設定 Label
- 選擇 Label,點擊右側的 Attributes inspector。
- 設定 Label 的 Text 為 2014。
- 設定 Label 的 Alignment 為 Center。
連結 IBOutlet
- 在 ViewController.swift 中,宣告 IBOutlet。
- 在 Main.storyboard 中,選擇 Date Picker,點擊右側的 Connections inspector。
- 將 Date Picker 的 New Referencing Outlet 連結到 ViewController 的 datePicker。
4. 在 Main.storyboard 中,選擇 Image View,點擊右側的 Connections inspector。
5. 將 Image View 的 New Referencing Outlet 連結到 ViewController 的 imageView。
6. 在 Main.storyboard 中,選擇 Slider,點擊右側的 Connections inspector。
7. 將 Slider 的 New Referencing Outlet 連結到 ViewController 的 slider。
8. 在 Main.storyboard 中,選擇 Label,點擊右側的 Connections inspector。
9. 將 Label 的 New Referencing Outlet 連結到 ViewController 的 yearLabel。
連結 IBAction
在 ViewController.swift 中,宣告 IBAction。
@IBAction func datePickerChanged(_ sender: UIDatePicker) {
}
@IBAction func sliderChanged(_ sender: UISlider) {
}
- 在 Main.storyboard 中,選擇 Date Picker,點擊右側的 Connections inspector。
- 將 Date Picker 的 Value Changed 連結到 ViewController 的 datePickerChanged。
- 在 Main.storyboard 中,選擇 Slider,點擊右側的 Connections inspector。
- 將 Slider 的 Value Changed 連結到 ViewController 的 sliderChanged。
實作功能
- 在 ViewController.swift 中,實作 datePickerChanged 函式。
@IBAction func datePickerChanged(_ sender: UIDatePicker) {
let selectedYear = Calendar.current.component(.year, from: sender.date)
updateUI(year: selectedYear)
}
2. 在 ViewController.swift 中,實作 sliderChanged 函式。
@IBAction func sliderChanged(_ sender: UISlider) {
let roundedValue = round(sender.value)
sender.value = roundedValue
let selectedYear = Int(roundedValue)
updateUI(year: selectedYear)
}
3. 在 ViewController.swift 中,實作 updateUI 函式。
func updateUI(year: Int) {
yearLabel.text = "\(year)"
datePicker.date = Calendar.current.date(from: DateComponents(year: year))!
slider.value = Float(year)
imageView.image = UIImage(named:"image(year)")
}
初始化
在 ViewController.swift 中,實作 viewDidLoad 函式。
override func viewDidLoad() {
super.viewDidLoad()
let initialYear = 2014
updateUI(year: initialYear)
}
這樣就完成了 10YearChallenge App 的基本功能。現在,當您滑動 Slider 或選擇 Date Picker 時,應用程式將顯示對應年份的圖片,並更新 Label 和其他 UI 元素。請確保您的專案中有名為 “image2014”、”image2015" 等的圖片資源。
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var datePicker: UIDatePicker!
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var slider: UISlider!
@IBOutlet weak var yearLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
let initialYear = 2014
updateUI(year: initialYear)
}
@IBAction func datePickerChanged(_ sender: UIDatePicker) {
let selectedYear = Calendar.current.component(.year, from: sender.date)
updateUI(year: selectedYear)
}
@IBAction func sliderChanged(_ sender: UISlider) {
let roundedValue = round(sender.value)
sender.value = roundedValue
let selectedYear = Int(roundedValue)
updateUI(year: selectedYear)
}
func updateUI(year: Int) {
yearLabel.text = "\(year)"
datePicker.date = Calendar.current.date(from: DateComponents(year: year))!
slider.value = Float(year)
imageView.image = UIImage(named: "image\(year)")
}
}
請 AI 幫忙的注意事項
彼得潘實測 App 後發現功能完全正確,AI 成功地寫出 10YearChallenge App,而且過程中還耐心地講解每個步驟。
不過 AI 也不是完美的,所以麻煩它寫程式時請注意以下幾點。
- AI 給出回答後,如果覺得他某個地方寫得不好,可以請他改進。請放心,他沒有心,不會傷心的。
ex: 請將圖片名字改成存在 array 的寫法,年份是 2014 ~ 2023。
class ViewController: UIViewController {
@IBOutlet weak var datePicker: UIDatePicker!
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var slider: UISlider!
@IBOutlet weak var yearLabel: UILabel!
let imageNames = (2014...2023).map { "image\($0)" }
var currentYearIndex = 0
override func viewDidLoad() {
super.viewDidLoad()
updateUI(year: 2014)
}
@IBAction func datePickerChanged(_ sender: UIDatePicker) {
let selectedYear = Calendar.current.component(.year, from: sender.date)
updateUI(year: selectedYear)
}
@IBAction func sliderChanged(_ sender: UISlider) {
let roundedValue = round(sender.value)
sender.value = roundedValue
let selectedYear = Int(roundedValue)
updateUI(year: selectedYear)
}
func updateUI(year: Int) {
yearLabel.text = "\(year)"
datePicker.date = Calendar.current.date(from: DateComponents(year: year))!
slider.value = Float(year)
imageView.image = UIImage(named: imageNames[currentYearIndex])
}
}
首先,我們可以先將圖片名字存在一個 array 中,然後再新增一個變數 currentYearIndex 來代表目前顯示的圖片在 array 中的 index。接著在 updateUI 方法中,將 imageView.image 的值改成 UIImage(named: imageNames[currentYearIndex]) 即可。最後在 viewDidLoad 方法中呼叫 updateUI(year: 2014) 即可初始化畫面。
- AI 可能寫錯,寫錯時我們可以自己修改,或是跟 AI 描述問題,請他再做修改。
剛剛加入圖片名字存在 array 的寫法後,程式出了問題,因此我們請 AI 再做修改。
ex: 程式有問題,currentYearIndex 一直維持 0。
看起來 currentYearIndex 的值一直都是 0,這應該是因為在 updateUI 方法中沒有更新 currentYearIndex 的值。我們可以在 updateUI 方法中加上以下程式碼來更新 currentYearIndex 的值:
if let index = imageNames.firstIndex(of: "image\(year)") {
currentYearIndex = index
}
這樣就可以讓 currentYearIndex 的值隨著年份的改變而更新了。
- AI 給出回答後,看不懂也可以問她。雖然她不是人,你還是可以幻想她是溫柔的程式老師。
ex: 我看不懂 Calendar.current.component(.year, from: sender.date)。
Calendar.current.component(.year, from: sender.date) 是一个获取日期中年份的方法。在这个例子中,我们从 UIDatePicker 中获取了一个日期,然后使用 Calendar.current 获取当前日历,最后使用 component 方法获取日期中的年份。这个方法返回一个 Int 类型的值,表示日期中的年份。
- AI 給出回答後,可以請他加入更多功能。
ex: 請在剛剛的 storyboard 加入一個隨機的 button,點選後會隨機某一年的圖片。
在 storyboard 中加入一個 button,並且在 ViewController 中加入以下程式碼:
@IBAction func randomButtonPressed (_ sender: UIButton) {
let randomYear = Int.random(in: 2014...2023)
updateUI (year: randomYear)
}
然後在 storyboard 中將 button 的 action 設定 randomButtonPressed。 這樣點選 button 後就會隨機顯示某一年的圖片了。