iOS 開發 #10 Alert 與 Sheet 的開啟方式 (下) Alert
前言
在上篇提到了 Sheet
的用法,這次來講講 Alert
的用法
Alert
在 App 中經常使用 AlertDialog 來提示、告知使用者必要的訊息
在 IBAction
中打入這段程式碼
let controller = UIAlertController(title: "標題", message: "訊息", preferredStyle: .alert)
let okAction = UIAlertAction(title: "OK", style: .default)
controller.addAction(okAction)
present(controller, animated: true)
就能在按下按鈕後跳出 Alert
的視窗
- title:設定
UIAlertController
的標題 - message:設定
UIAlertController
要顯示的訊息 - preferredStyle:設定
UIAlertController
的模式。他有兩種.alert
跟.actionSheet
可以選 - addAction:設定
UIAlertController
的按鈕 - present:設定欲顯示的
UIAlertController
與是否要有動畫
下面兩張圖是 preferredStyle: .alert
跟 preferredStyle: .actionSheet
這兩個模式顯示的視窗
上面提到的 title
、message
、present
應該都沒什麼問題,看到名字後就能猜到他是什麼意思,addAction
雖然看得出是什麼,但 addAction
要什麼設定這應該是剛接觸 Alert
時會遇到的問題
首先 addAction
他接受一個 UIAlertAction
的物件
所以我們可以建立一個 UIAlertAction
的物件
他需要三個參數:title
、style
以及 handler
title
:設定按鈕顯示的內容style
:設定按鈕的風格。有.default
、.cancel
、.destructive
三種handler
:設定按鈕按下所要做的事
呼叫多次的 addAction
可以加入多個按鈕
上面有提到 handler
可以新增按鈕的點擊事件,那要怎麼做呢?
把要做的事情加在 UIAlertAction
後面就好了
例如:
let okAction = UIAlertAction(title: "OK", style: .destructive) { _ in
print("OK")
}
這樣在按下 Alert
的按鈕後就會 print
出 OK
如果在 UIAlertAction
後面加上 {}
時會發現跳出錯誤了
不用緊張,這是代表你少打了一些東西,下面請我最好的工作夥伴 ChatGPT 來解釋一下關於 UIAlertAction
這個錯誤訊息 Contextual type for closure argument list expects 1 argument, which cannot be implicitly ignored
是因為在 UIAlertAction
的閉包中,系統預期你需要處理一個參數,但你在定義閉包時,沒有明確地接收這個參數
UIAlertAction
是什麼
UIAlertAction
是 iOS 中用來在 UIAlertController
(一個彈出視窗)中添加按鈕選項的類別。每個 UIAlertAction
代表一個按鈕,當按鈕被點擊時,會執行與該按鈕相關聯的動作。這個動作通常以閉包的形式提供,閉包允許在按鈕被點擊後執行一段自定義的程式碼
為什麼需要使用閉包
閉包是一段自包含的功能代碼,可以在你的應用程式中傳遞和使用。當你在建立 UIAlertAction
時,你可以使用閉包來定義在按下按鈕時所要執行的程式碼邏輯
錯誤的原因
當你創建一個 UIAlertAction
,其閉包函數預期會接收一個參數,這個參數是 UIAlertAction
本身。然而,你的閉包沒有接收這個參數,這導致了編譯器不滿意的錯誤
let okAction = UIAlertAction(title: "OK", style: .destructive) { action in
print("OK")
}
在上面的 Code 中,action
是一個 UIAlertAction
類型的參數,表示按下的這個按鈕。雖然你可能不使用這個參數,但你仍然需要明確地接收它。這樣就可以避免編譯器的錯誤
可忽略的情況
如果你確定不需要使用這個參數,可以用 _
來忽略它:
let okAction = UIAlertAction(title: "OK", style: .destructive) { _ in
print("OK")
}
上面講的 UIAlertAction
是按鈕,那 UIAlertController
可以加上 Text Field
嗎?
當然可以,這就需要用到 .addTextField
來新增 Text Field
let controller = UIAlertController(title: "標題", message: "訊息", preferredStyle: .alert)
controller.addTextField { textField in
textField.placeholder = "Hint"
}
let okAction = UIAlertAction(title: "OK", style: .default) { _ in
let text = controller.textFields?[0].text
print(text ?? "")
}
controller.addAction(okAction)
present(controller, animated: false)
可以看到程式碼中新增一段
controller.addTextField { textField in
textField.placeholder = "Hint"
}
就是透過 addTextField
來把 Text Field
加入到 Alert
中
那因為 addTextField
也是閉包,所以也接收一個參數,而我這邊把這個參數叫做 textField
是因為我要調整 textField
的 placeholder
讓這個 Text Field
裡面有一個提示供使用者知道要輸入什麼東西
那要怎麼取資料呢?
這時需要到 action
裡面用 controller.textFields?[0].text
來取值,這邊用 [0]
是因為我只有一個 Text Field
,還有在上面的 Code 中,我的 print(text ?? "")
這邊好像怪怪的,其實這段是表示當 controller.textFields?[0].text
取到值時會讓 text = controller.textFields?[0].text
,而沒取到值時會讓 text = ""
,這樣能確保 text
裡面會有字串,即便是空字串也不會因為沒取到值讓 text = nil
使程式閃退
對於 Alert
其他用法有興趣,可以參考一下這篇文章
結論
這篇介紹了 UIAlertAction
模式與使用方法,透過上篇的 Sheet
跟這篇的 Alert
就可以讓使用者使用 APP 時有一個良好的體驗