swift5 AlertController 実装
やりたいこと Actionsheetで表示する
目的:ActionSheetをたくさん書きたくない。リテラル入力ミスを防ぎたい
解決法 EnumとforEachでのループ
EnumのCaseIterableとは
CaseIterable型を使用する場合、型のallCasesプロパティを使用して、 型のすべてのケースのコレクションにアクセスできます。
CaseIterableでループが回せる
どんな型でも利用可能
enum Term: String, CaseIterable { case Day = "Day" case Week = "Week" case _2Weeks = "2 Weeks" case _1Month = "1 Month" case _3Months = "3 Months" case Year = "Year" case _2Years = "2 Years" case _3Years = "3 Years" /// In seconds var timeIntervalValue: Int { switch self { case .Day: return 60*60*24 case .Week: return Term.Day.timeIntervalValue * 7 case ._2Weeks: return Term.Week.timeIntervalValue * 2 case ._1Month: return Term.Day.timeIntervalValue * 30 case ._3Months: return Term._1Month.timeIntervalValue * 3 case .Year: return Term.Day.timeIntervalValue * 365 case ._2Years: return Term.Year.timeIntervalValue * 2 case ._3Years: return Term.Year.timeIntervalValue * 3 } } } //Enumを格納しておくメンバ変数を用意する /// Between var term:Term? /// How long var period:Period?
ループ箇所
@IBAction func termButtonTapped(_ sender: Any) { //UIAlertControllerを作成しておく let termAlert = UIAlertController(title: "Term", message: "Select Term", preferredStyle: .actionSheet) //enumをループする Term.allCases.forEach { //loopの要素は$0でget let term = $0 //ここは第3引数をclosureにした 下記参照 let termAction = UIAlertAction(title: term.rawValue, style: .default) { _ in //Firebaseで検索するため、メンバ変数に保存しておく self.term = term //ボタンに値をセット self.termButton.setTitle(term.rawValue, for: .normal) } termAlert.addAction(termAction) } present(termAlert, animated: true, completion: nil) }
UIAlertAction関数定義
引数3つ最後の引数をClosureに変更
TrailingClosureという
このサイトはクロージャーを学ぶには大変参考になる 英語読まないと力つかない
Closures — The Swift Programming Language (Swift 5.4)
open class UIAlertAction : NSObject, NSCopying { public convenience init(title: String?, style: UIAlertAction.Style, handler: ((UIAlertAction) -> Void)? = nil)