フルスクリーンではない画面作成Part３〜フェードアウトイン編〜

みなさんこんにちは。夢はフリーランスエンジニアのあがです。今回は少しでもカッコよくViewを登場させてみようとアニメーションに挑戦してみようと思います！
関数を作ってフェードインとフェードアウトのアニメーション作成をしていきます！！
##前回までの記事はこちら
[フルスクリーンではない画面作成Part1](https://qiita.com/agachan0930/items/00cb8783ea70a12f9ece)
[フルスクリーンではない画面作成Part2](https://qiita.com/agachan0930/items/fd30538d26599a25f6cc)
影をつけるのは箸休めとして今回は難易度高めで行きます！！
##今回作りたいもの
うまく作り方がわからないのでYouTubeにアップして作成しました・・・
[作るviewはこちらから！！](https://www.youtube.com/watch?v=O8SD-4FxqRw&feature=youtu.be)
##どんな風に作るのかをイメージしよう！！
###[Point1]初期設定は透明であること
今までのコードでは前提条件としてRegistViewが透明ではない。つまりどれだけ設定をしても１回目に表示をさせた時にいきなりViewが表示をされる感じになっている
解決方法→viewWillAppearで画面が表示される前の設定をする
[viewWillAppearに関する記事はこちら](https://qiita.com/entaku0818/items/87d4e7225e23db0b01ff)
これはほんまに理解するのが難しいので関連記事などを探って自分なりに理解することがおすすめです！！

###[Point２]Buttonが押された時にViewが出てきたり消えたりする
viewが出てくる関数addSubView()にアニメーションの何かしらつけることでできそう！！
[アニメーションに関する記事はこちら](https://qiita.com/maebaru/items/fb851f533615e2e252a4)
###[Point3]RegistButtonが押されて表示された時にもう一度押せないような設定にする
この時にOutletで接続をしていないとボタンが変更できないことに注意をする！！
押せるかどうか関しては以下のコードを用いると良い

```swift
@IBOutlet weak var showRegistButton: UIBarButtonItem!
@IBAction func showRegistView(_ sender: Any) {
//Bool型(「できる！」か「できない！」で返す関数のこと)でボタンが押された時に次にタップできるかを操作できる
        showRegistButton.isEnabled = false
    }
```
falseの場合→ボタンが押せなくなる！！
trueの場合→ボタンが押せるようになる！！

##実際に設置をして解説をしていきます！！

```swift:
import UIKit

class ViewController: UIViewController{

    override func viewDidLoad() {
        super.viewDidLoad()
        
    }
    
//変更点⓵
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        registView.alpha = 0.0
    }
    
    func setRegistVIew(){
        let screenFrameX = self.view.frame.width/2
        let screenFrameY = self.view.frame.width/2
        let viewX = 300
        let viewY = viewX*4/3

        registView.layer.cornerRadius = 20
        registView.layer.shadowOffset = CGSize(width: 0, height: 2)
        registView.layer.shadowColor = UIColor.darkGray.cgColor
        registView.layer.shadowOpacity = 0.5
        registView.layer.shadowRadius = 4
        registView.frame = CGRect.init(x: Int(screenFrameX)-viewX/2, y: Int(screenFrameY), width: viewX, height: viewY)
        setSaveButton()
    }
    
    func setSaveButton(){
        saveButton.layer.cornerRadius = 10
        saveButton.tintColor = .white
        saveButton.backgroundColor = .red
        saveButton.layer.shadowOffset = CGSize(width: 0, height: 2)
        saveButton.layer.shadowColor = UIColor.darkGray.cgColor
        saveButton.layer.shadowOpacity = 0.5
        saveButton.layer.shadowRadius = 4
    }
        
//変更点②
    @IBOutlet weak var showRegistButton: UIBarButtonItem!
    @IBOutlet var registView: UIView!
    @IBOutlet weak var saveButton: UIButton!
    
//変更点③
    @IBAction func showRegistView(_ sender: Any) {
        FadeInAnimationView(duration: 0.3, delay: 0.0, alpha: 1.0,baseView: self.view,addView: registView)
        showRegistButton.isEnabled = false
        setRegistVIew()
    }

//変更点④
    @IBAction func saveButton(_ sender: Any) {
        FadeOutAnimationView(duration: 0.3, delay: 0.0, alpha: 0.0, removeView: registView)
        showRegistButton.isEnabled = true
    }
    
//変更点⑤
    func FadeInAnimationView(duration:Double,delay:Double,alpha:Double,baseView:UIView,addView:UIView){
        UIView.animate(withDuration:TimeInterval(duration),
                       delay: TimeInterval(delay),
                       options: .curveEaseOut,
                       animations: {addView.alpha = CGFloat(alpha)})
        baseView.addSubview(addView)
    }
    
//変更点⑥
    func FadeOutAnimationView(duration:Double,delay:Double,alpha:Double,removeView:UIView){
        UIView.animate(withDuration:TimeInterval(duration),
                       delay: TimeInterval(delay),
                       options: .curveEaseOut,
                       animations: {removeView.alpha = CGFloat(alpha)}){ (completed) in
                        removeView.removeFromSuperview()
                   }
    }
}
```

###変更点①
[Point1]でも紹介した通り初期状態の透明度が１.0になっているのでいきなり表示されるのはアニメーションを無視して表示される
###変更点②
[Point3]でも紹介した通りActionの中にOutletを入れることで表示を変更させることができる
###変更点③と④
[Point2]で紹介した[リンク](https://qiita.com/maebaru/items/fb851f533615e2e252a4)を参考にしてアニメーションを作成してみた

```swift:showRegistView()
//フェードインにはFadeInAnimationView(duration：アニメーションに時間,
//                                  delay：ボタンが押されてから何秒後にアニメーションを開始させるか,
//                                  alpha：アニメーションが終わった際に透明度はどれぐらいにするか,
//                               baseView：どのViewに対して画面を追加するか
//                                addView：どのviewを追加するか)
FadeInAnimationView(duration:Double,delay:Double,alpha:Double,baseView:UIView,addView:UIView)
FadeInAnimationView(duration: 0.3, delay: 0.0, alpha: 1.0,baseView:self.view, addView: registView)
```

```swift:saveButtoon()
//フェードインにはFadeOutAnimationView(duration:アニメーションに時間,
//                                  delay:ボタンが押されてから何秒後にアニメーションを開始させるか,
//                                  alpha:アニメーションが終わった際に透明度はどれぐらいにするか,
//                             removeView：どのviewを消すのか)
FadeOutAnimationView(duration:Double,delay:Double,alpha:Double,View:UIView)
FadeOutAnimationView(duration: 0.3, delay: 0.0, alpha: 0.0, removeView: registView)
```
[Point3]でも用いた関数をそのまま入れましたフェードインする時にはfalseにしてボタンを押せないようにして、フェードアウトの時にはtrueにして押せるようにしている
###変更点⑤と⑥
[Point2]で紹介した[リンク](https://qiita.com/maebaru/items/fb851f533615e2e252a4)を参考にしてアニメーションを作成してみた
フェードインでは画面が追加される操作とアニメーションを独立させないとアニメーションが動作しない
フェードアウトではアニメーションと画面が消える設定を連動させないと画面が消えない
ため二つのコードには若干の違いがある

```swift:FadeInAnimationView
 func FadeInAnimationView(duration:Double,delay:Double,alpha:Double,baseView:UIView,addView:UIView){
        UIView.animate(withDuration:TimeInterval(duration),
                       delay: TimeInterval(delay),
//等速で表示を変更する
                       options: .curveEaseOut,
                       animations: {addView.alpha = CGFloat(alpha)})
        baseView.addSubview(addView)
    }
```

```swift:FadeOutAnimationView
func FadeOutAnimationView(duration:Double,delay:Double,alpha:Double,removeView:UIView){
        UIView.animate(withDuration:TimeInterval(duration),
                       delay: TimeInterval(delay),
                       options: .curveEaseOut,
                       animations: {removeView.alpha = CGFloat(alpha)}){ (completed) in
                        removeView.removeFromSuperview()
                   }
    }
```

この関数はどの場面においても使えるので便利だと思います！！是非使っていただけるとありがたいです！！