【Swift5】リアルタイムグラデーション背景を実装する【IBDesignable】【IBInspectable】

## なんで標準でグラデーション機能ついてないの！！！

冒頭から大声ですみません。普段IllustratorやVSCodeでのGUIお手軽デザインに甘やかされてるので、グラデーションを実装するためにコーディングするのが不満でしょうがなかったのです。
で、~~Apple様に訴えるため~~ 学びの整理とみなさまへの共有のため記事化します。

初学者ゆえ、不適切な表現やコードがあるかと思います。その際は優しくご指導いただけますと幸いです。


## まずはGoogleで先人の知恵を探す
techno monkey様の記事を参考に、コメントで解説をつけながらやってみる。
[Swift UIViewの背景をグラデーションさせる方法　-iPhoneアプリ開発-](https://techno-monkey.com/swift-uiview-gradation-iphoneapp/)

```swift:ViewController.swift
import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // グラデーションレイヤーを用意
        let gradientLayer = CAGradientLayer()
        gradientLayer.frame = self.view.bounds // gradientLayerのサイズを指定？
        
        // グラデーションさせる色の指定
        let color1 = UIColor.orange.cgColor // オレンジ
        let color2 = UIColor.red.cgColor // 赤
        
        // CAGradientLayerに色を設定（ここでたくさん色を指定することも可能？）
        gradientLayer.colors = [color1, color2]
        
        // グラデーションの開始点、終了点を設定（0~1）
        gradientLayer.startPoint = CGPoint.init(x: 0.5, y: 0) // 画面上中央
        gradientLayer.endPoint = CGPoint.init(x: 0.5, y: 1) // 画面下中央
        
        // ViewControllerの親Viewレイヤーにグラデレイヤーを挿入する
        self.view.layer.insertSublayer(gradientLayer, at: 0)
    }

}
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636889/e6a10765-8c81-33f8-29a2-695f78ff94b7.png" width=40% />
いい感じ。とっても綺麗なグラデーションの出来上がり。



## ちゃうねん、StoryBoardでリアルタイムに確認したいねん

これで要件は満たしているけれども、この実装方法だと**StoryBoardではグラデーションがプレビューされない。**
**StoryBoardで背景との兼ね合いを考えながら文字色やボタンの配置を行いたい。**

## <span>@</span>IBDesignableね
Swiftには<span>@</span>IBDesignableと<span>@</span>IBInspectableという、StoryBoardのGUI上で設定できる項目を増やす方法が用意されているらしい。
なるほどね、これでGUIでのカスタマイズ機能が追加し放題というわけだ。さすがApple様。
### 早速やってみる！

`File -> New -> File...`で新しいSwiftファイルを作成する。ここではGradient.swiftと命名（←こういうファイル名はどんな規則に則って決めれば良いのだろう）。

```swift:Gradient.swift
import UIKit

@IBDesignable
final class GradientView: UIView {
    
    @IBInspectable var Color1: UIColor = UIColor.orange
    @IBInspectable var Color2: UIColor = UIColor.red
    
    @IBInspectable var Position1: CGPoint = CGPoint.init(x: 0.5, y: 0)
    @IBInspectable var Position2: CGPoint = CGPoint.init(x: 0.5, y: 1)
    
    // 実際の描画
    override func draw(_ rect: CGRect) {
        // グラデーションレイヤーを用意
        let gradientLayer = CAGradientLayer()
        // gradientLayerのサイズを指定
        gradientLayer.frame = self.bounds
        
        // グラデーションさせる色の指定
        let color1 = Color1.cgColor
        let color2 = Color2.cgColor
        
        // CAGradientLayerに色を設定（ここでたくさん色を指定することも可能？）
        gradientLayer.colors = [color1, color2]
        
        // グラデーションの開始点、終了点を設定（0~1）
        gradientLayer.startPoint = Position1
        gradientLayer.endPoint = Position2
        
        // ViewControllerの親Viewレイヤーにレイヤーを挿入する
        self.layer.insertSublayer(gradientLayer, at: 0)
    }
    
}
```
これでコーディング部分は完了。`ViewController.swift`に書いたときと微妙に異なる部分があるので注意。

### StoryBoardにUIViewを配置
![Screen Shot 2021-02-08 at 23.20.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636889/916d0b1c-c3cb-52bb-3359-8d22dba92430.png)

### Classを指定
さっき配置したUIViewにClassを指定する
![Screen Shot 2021-02-08 at 23.23.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636889/d0e800b8-a6eb-2d7f-745f-b70796fce0f4.png)
正しくできていればこんな感じで入力予測が出てくる。

## 完璧じゃん？
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636889/7f05db50-50a3-5607-cc2d-a8049731dcb4.png" width=30% />

あとはこのUIViewを画面全体に広げたり、Auto Layoutしたりして**簡単にグラデーションが使える！**

### 設定も自由
![Screen Shot 2021-02-08 at 23.31.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636889/ed3024c4-c734-bec1-efa1-ac6ec05d9fd8.png)
こんな感じに設定すると

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636889/9537d2d7-0842-6eb2-31ec-71c19a88bcac.png" width=30% />
左上（0, 0）から右下（1, 1）にかけてグラデーションするViewができる（**リアルタイムプレビューで**）。


## おしまい

GUIでできることはGUIでやりたいよね。