きっかけ
swiftで
・enumをとにかく使ってみたい
・closureも使ってみたい
というのを考えていて、とりあえず思いついたのが、同じUIAlertControllerをボタンによって動向を変えるということだった。
開発環境
・Xcode version 7.3
完成品
・三色のボタンを押すと、それぞれ異なるタイトルを持つアラートが表示され、上のLabelが切り替わるというもの。
・どのボタンを押しても発動する関数は同じだが、enumとclosureを分けることで処理を変えることができる
完成品のコード
import UIKit
//ボタンの色専用の型
enum ButtonColor{
case Red
case Blue
case Green
}
class EnumClosureTest: UIViewController {
//一番上のテキストラベル
@IBOutlet weak var msgTextLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
//赤いボタンを押す
@IBAction func tapRedButton(sender: AnyObject) {
displayAlert(.Red)
}
//青いボタンを押す
@IBAction func tapBlueButton(sender: AnyObject) {
displayAlert(.Blue)
}
//緑のボタンを押す
@IBAction func tapGreenButton(sender: AnyObject) {
displayAlert(.Green)
}
//アラートを表示ー>テキストラベルを変更する関数
func displayAlert(color: ButtonColor){
let alertController = UIAlertController(title: "", message: "", preferredStyle: .Alert)
//色によってクロージャーを変える
var closure: (UIAlertAction)->Void
//色の型で場合分け(enum型の場合defaultはいらない)
switch color {
case .Red:
alertController.title = "Redを押しました"
closure = {(action)->Void in
self.msgTextLabel.text = "Red!"
}
case .Blue:
alertController.title = "Blueを押しました"
closure = {(action)->Void in
self.msgTextLabel.text = "Blue!"
}
case .Green:
alertController.title = "Greenを押しました"
closure = {(action)->Void in
self.msgTextLabel.text = "Green!"
}
}
//okボタンを押した時の処理。クロージャーを変えることで変更できる。
let okAction = UIAlertAction(title: "OK", style: .Default, handler: closure)
alertController.addAction(okAction)
//キャンセル時の処理。特別なにもしないのでコンパクトにまとめてしまう
alertController.addAction(UIAlertAction(title: "cancel", style: .Cancel, handler: nil))
//alertを出す
presentViewController(alertController, animated: true, completion: nil)
}
}
//UIButtonのサブクラス(見た目だけ変更)
class CustomButton: UIButton {
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
backgroundColor = UIColor.clearColor()
self.layer.cornerRadius = self.bounds.height/2
self.layer.borderWidth = 2
}
}
class CustomButtonRed: CustomButton{
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.layer.borderColor = UIColor.redColor().CGColor
}
}
class CustomButtonBlue: CustomButton{
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.layer.borderColor = UIColor.blueColor().CGColor
}
}
class CustomButtonGreen: CustomButton{
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.layer.borderColor = UIColor.greenColor().CGColor
}
}
・これらをそれぞれのUIパーツに登録すれば、押すボタンによって処理を変えることができるようになる
結論
・enumのメリットは考えるに、こういった限定的な分岐をさせたい場合に、変な文字列が入らないように限定してくれることだと思う。
・だから別にenumにする必要はなくて
func displayAlert(color: String){
let alertController = UIAlertController(title: "", message: "", preferredStyle: .Alert)
//色によってクロージャーを変える
var closure: (UIAlertAction)->Void
//色の型で場合分け(enum型の場合defaultはいらない)
switch color {
case "Red":
alertController.title = "Redを押しました"
closure = {(action)->Void in
self.msgTextLabel.text = "Red!"
}
case "Blue":
alertController.title = "Blueを押しました"
closure = {(action)->Void in
self.msgTextLabel.text = "Blue!"
}
case "Green":
alertController.title = "Greenを押しました"
closure = {(action)->Void in
self.msgTextLabel.text = "Green!"
}
}
//以下略
........としてもいいわけだけども、これだとYellow
とか変なものが入ってきかねない。
・これでなんとなくenumの利便さがわかってきた........ようなきがする
・closureは言わずもがな、サクッと処理が変えれて便利だなと思った。