UIAlertControllerのボタンの文字色を変更する(iOS8,9対応)

アプリ内で、アラート(UIAlertController)のボタンの文字をUIAppearanceで一括変更していたのですが、
iOS9だと反映されていないことに気づき、その対応をしたときのメモです。
また、

```swift
    UIView.appearance().tintColor = UIColor.greenColor()
    UITextField.appearance().tintColor = UIColor.greenColor()
```

に近い書き方ができるようにしてみました。

## 試した環境
- Xcode 7.0
- Swift 2.0
- iOS8,9共に動作

## コード
*extension*と、*Method Swizzling*を用いてます。

```swift:UIAlertController+Appearance.swift

import Foundation
import UIKit

extension UIAlertController {
    
    class Appearance {
        
        private static let sharedInstance = Appearance()

        var tintColor: UIColor?

        private init() {
        }
        
        class func appearance() -> Appearance {
            return sharedInstance
        }
        
    }
    
    class func appearance() -> Appearance {
        return Appearance.appearance()
    }
    

    public override class func initialize() {
        struct Static {
            static var onceToken: dispatch_once_t = 0
        }
        dispatch_once(&Static.onceToken) {
            let originalSelector = Selector("viewWillLayoutSubviews")
            let swizzledSelector = Selector("swizzle_viewWillLayoutSubviews")
            
            let originalMethod = class_getInstanceMethod(self, originalSelector)
            let swizzledMethod = class_getInstanceMethod(self, swizzledSelector)
            
            let didAddMethod = class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))
            if didAddMethod {
                class_replaceMethod(self, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
            } else {
                method_exchangeImplementations(originalMethod, swizzledMethod);
            }
        }
    }
    
    func swizzle_viewWillLayoutSubviews() {
        swizzle_viewWillLayoutSubviews()
        self.view.tintColor = self.dynamicType.appearance().tintColor
    }
    
}
```

こんな感じで実装すると、以下のように書いて変更ができます。

```swift
    UIAlertController.appearance().tintColor = UIColor.purpleColor()
```

途中で色を変えることももちろん可能です。

```swift
// 注 : UIViewController内を想定
    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)
        UIAlertController.appearance().tintColor = UIColor.purpleColor()
        
        let alert = UIAlertController(title: "test", message: "test message", preferredStyle: .Alert)
        alert.addAction(UIAlertAction(title: "dismiss", style: .Default, handler: { [unowned self] _ in
            
            UIAlertController.appearance().tintColor = UIColor.greenColor()
            let alert = UIAlertController(title: "test2", message: "test message2", preferredStyle: .Alert)
            alert.addAction(UIAlertAction(title: "dismiss", style: .Default, handler: nil))
            self.presentViewController(alert, animated: true, completion: nil)
            
        }))
        
        self.presentViewController(alert, animated: true, completion: nil)
    }

```

#### 注意書き
**注1)** 現状、*UIAlertController.appearance()*がないので問題はないですが、将来的に同名の関数が定義されて、標準で変更可能となった場合は衝突する可能性はあります。とりあえず、現状では問題はないということで。

**注2)** Method Swizzlingを用いているので、あまりそういうのは...という方は、下記参考にさせていただいた記事の方を参照して、
UIAlertControllerを継承する形で対応するほうがよいかもしれません。
Method Swizzlingしておりますが、動作に関しては問題ありません。


## 参考にさせていただいた記事

- iOS9でUIAlertControllerのテキストカラーを変更する  
http://qiita.com/katsuhisaishii/items/2547230452f48f115f3d

→Objective-Cでの同様の対応方法について書かれています。