[iOS] Xibを使って自前のダイアログを作る

#きっかけ
Androidとおなじにしてよ。っていわれたのが最初のきっかけです。
IDやパスワードを入力したり、カスタマイズがしやすいようにXibでAlertViewが簡単に作れるといいなと思いました。

今までこんな書き方をよく使ってましたが
```self.presentViewController(vc, animated: true, completion: nil)
```
Viewを上に重ねるだけでなく、Alertっぽくしたい！！っていうのが一番の希望。

##でも
でも、実際Alertなわけではなく、ViewControllerをAlertっぽくみせているだけです

##プロジェクトを作る
###シングルビューアプリケーションでプロジェクトを作ります
<img width="500" alt="ss00.png" src="https://qiita-image-store.s3.amazonaws.com/0/6323/81549384-0fe0-c135-7bcf-43f7bd2a2c33.png">

###プロジェクト名を入力します
<img width="500" alt="ss02.png" src="https://qiita-image-store.s3.amazonaws.com/0/6323/74448b5e-997d-6ac0-407e-bff118d89dac.png">


##Alertに使うViewControllerを作ります
###メニューからFile-New-FileでCocoa Touch Classを選択します。

<img width="500" alt="ss01.png" src="https://qiita-image-store.s3.amazonaws.com/0/6323/6f01a06c-913a-5178-0870-fa67b25924e1.png">

###ViewControllerの名前をつけます
*Also create XIB fileにチェックをつけます
<img width="500" alt="ss03.png" src="https://qiita-image-store.s3.amazonaws.com/0/6323/50b42d88-92a6-88ad-0e34-66b0c40da4b6.png">

###出来上がったMyAlertViewController.swiftを修正します
*画面遷移のアニメーションをカスタマイズするのでUIViewControllerTransitioningDelegateを追加します
<img width="500" alt="ss04.png" src="https://qiita-image-store.s3.amazonaws.com/0/6323/98ee61a5-9ce7-a664-c0ba-e4c9bd3ae938.png">

##外観のカスタマイズ
MyAlertViewController.Xibにボタンをつけたり、タイトルをつけてMyAlertViewController.swiftとOutletで結んでください。
<img width="400" alt="ss06.png" src="https://qiita-image-store.s3.amazonaws.com/0/6323/8d5775b4-e245-ba3c-79d5-e1335ee9b923.png">

##MyAlertViewController.swiftを編集
###３つのinit

1.xibを初期化するinit。背景を透明にしたり、アニメーションをカスタマイズする設定をします

```swift:MyAlertViewController.swift
override init(nibName nibNameOrNil:String?, bundle ninBundleOrNil:Bundle? ){
        super.init(nibName:nibNameOrNil,bundle:ninBundleOrNil)
        self.transitioningDelegate = self
        self.providesPresentationContextTransitionStyle = true
        self.definesPresentationContext = true
        self.modalPresentationStyle = .custom
        
    }
```
2.実際に使用する初期化処理です

```swift:MyAlertViewController.swift
    convenience init(title:String,desc:String){
        self.init(nibName:"MyAlertViewController",bundle:nil)
        titleText = title
        messageText = desc
    }
```
3.普通のinitは使わないのでエラーにします    

```swift:MyAlertViewController.swift
    required init?(coder aDecider: NSCoder){
        fatalError("init error")
    }
```    

###UIViewControllerTransitioningDelegate

デフォルトのアニメーションだと画面下から上に移動するアニメーションなので書き換えます

```swift:MyAlertViewController.swift
    func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return AlertAnimation(show:true)
    }
    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return AlertAnimation(show:false)
    }
```

###アニメーションの実態を書きます

>
class MyAlertViewController: UIViewController,UIViewControllerTransitioningDelegate {

の最後の括弧「}」が閉じてから下に付け足すか、もしくは別ファイルにしてください

```swift:MyAlertViewController.swift
class AlertAnimation : NSObject, UIViewControllerAnimatedTransitioning {
    
    let show: Bool
    
    init(show: Bool) {
        self.show = show
    }
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        if (show) {
            return 0.45
        } else {
            return 0.25
        }
    }
    
    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        if (show) {
            self.presentAnimateTransition(transitionContext: transitionContext)
        } else {
            self.dismissAnimateTransition(transitionContext: transitionContext)
        }
    }
    
    func presentAnimateTransition(transitionContext: UIViewControllerContextTransitioning) {
        
        let alertVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to) as! MyAlertViewController
        alertVC.view.frame = UIScreen.main.bounds
        let containerView = transitionContext.containerView
        alertVC.alertView.alpha = 0.0
        alertVC.alertView.center = alertVC.view.center
        alertVC.alertView.transform = CGAffineTransform.init(scaleX: 0.5, y: 0.5)
        containerView.addSubview(alertVC.view)
        
        UIView.animate(withDuration: 0.25,
                       animations: {
                                    alertVC.view.alpha = 1.0
                                    alertVC.alertView.alpha = 1.0
                                    alertVC.alertView.transform = CGAffineTransform.init(scaleX: 1.05, y:1.05)
        },
                                   completion: { finished in
                                    UIView.animate(withDuration:0.2,
                                                    animations: {
                                                    alertVC.alertView.transform = CGAffineTransform.identity
                                    },
                                                    completion: { finished in
                                                            if (finished) {
                                                                    transitionContext.completeTransition(true)
                                                            }
                                    })
        })
    }
    func dismissAnimateTransition(transitionContext: UIViewControllerContextTransitioning) {
        
        let alertVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from) as! MyAlertViewController
        
        UIView.animate(withDuration:self.transitionDuration(using: transitionContext),
                                   animations: {
                                    alertVC.view.alpha = 0.0
                                    alertVC.alertView.alpha = 0.0
                                    alertVC.alertView.transform = CGAffineTransform.init(scaleX: 0.9, y: 0.9)
        },
                                   completion: { finished in
                                    transitionContext.completeTransition(true)
        })
    }
}
```

##ソース
[GitHubにおきました](https://github.com/NaokoKubo/CustomAlertView)