Swiftのenumとclosureを使ってAlertの動向を変えてみる


#きっかけ
swiftで
・enumをとにかく使ってみたい
・closureも使ってみたい
というのを考えていて、とりあえず思いついたのが、同じUIAlertControllerをボタンによって動向を変えるということだった。

#開発環境
・Xcode version 7.3

#完成品
・とりあえず全体像
![代替テキスト](https://dl.dropboxusercontent.com/s/vrwr84o0jviqqdq/img1.png?dl=0)

・三色のボタンを押すと、それぞれ異なるタイトルを持つアラートが表示され、上のLabelが切り替わるというもの。

・どのボタンを押しても発動する関数は同じだが、enumとclosureを分けることで処理を変えることができる

#完成品のコード
```swift
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にする必要はなくて

```swift
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は言わずもがな、サクッと処理が変えれて便利だなと思った。