【Swift】よくみかける立体的で丸いボタンをコードで作ってみた(解説付き)

よく色々なアプリで見かける立体的で丸いボタンを作ってみました。
こんなやつです。
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480691/d0465836-e234-3a6a-9440-2044d84f7a8b.png">

##環境
Xcode12.4
Swift5

#コード全体
先に上記で作成したボタンのコードを載せておきます。

```swift
import UIKit

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // ボタン作成
        let customButton = UIButton()

        // スクリーンサイズ取得
        let screenWidth:CGFloat = self.view.frame.width
        let screenHeight:CGFloat = self.view.frame.height

        // ボタンサイズ指定
        let buttonWidth: CGFloat = 100
        let buttonHeight: CGFloat = 100

        // ボタンに反映（中央に位置調整）
        customButton.frame = CGRect(
            x: screenWidth/2-buttonWidth/2,
            y: screenHeight/2-buttonHeight/2,
            width: buttonWidth,
            height: buttonHeight)

        // ボタンの背景色
        customButton.backgroundColor = UIColor.white

        // アプリ標準のシステム画像を設定
        customButton.setImage(UIImage(systemName: "location.fill"), for: .normal)
        // 画像の色をdarkGrayに変更
        customButton.tintColor = .darkGray

        // 縦幅・横幅いっぱいに画像を表示
        customButton.contentHorizontalAlignment = .fill
        customButton.contentVerticalAlignment = .fill

        // ボタンを丸くする(サイズ/2で設定)
        customButton.layer.cornerRadius = 50
        // 画像を縮小する(マージンのようなもの)
        customButton.imageEdgeInsets = UIEdgeInsets(top: 30, left: 30, bottom: 30, right: 30)

        // 影の色
        customButton.layer.shadowColor = UIColor.black.cgColor
        // 影のぼかし？
        customButton.layer.shadowRadius = 3
        // 影の位置
        customButton.layer.shadowOffset = CGSize(width: 1.5, height: 1.5)
        // 影の濃さ
        customButton.layer.shadowOpacity = 0.3

        // ボタンをViewに追加
        view.addSubview(customButton)
    }
}
```

#解説
##ボタン作成
まずはボタンを作って、画像を設定してみます。
ボタンの背景色は白だと見えないので一時的にlightGrayに設定。

```swift
// ボタン作成
let customButton = UIButton()

// スクリーンサイズ取得
let screenWidth:CGFloat = self.view.frame.width
let screenHeight:CGFloat = self.view.frame.height

// ボタンサイズ指定
let buttonWidth: CGFloat = 100
let buttonHeight: CGFloat = 100

// ボタンに反映（中央に位置調整）
customButton.frame = CGRect(
    x: screenWidth/2-buttonWidth/2,
    y: screenHeight/2-buttonHeight/2,
    width: buttonWidth,
    height: buttonHeight)

// ボタンの背景色を設定(わかりやすいように一時的にlightGrayを設定)
customButton.backgroundColor = UIColor.lightGray

// アプリ標準のシステム画像を設定
customButton.setImage(UIImage(systemName: "location.fill"), for: .normal)
// 画像の色をdarkGrayに変更
customButton.tintColor = .darkGray

// ボタンをViewに追加
view.addSubview(customButton)
```
見た目はこんな感じです。
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480691/b38b1897-7054-f67f-1d93-bb6ebcfd09bd.png">
##画像を幅いっぱいに広げる
画像を大きくしたいのでAligmentをfillにして幅いっぱいにする

```swift
// 縦幅・横幅いっぱいに画像を表示
customButton.contentHorizontalAlignment = .fill
customButton.contentVerticalAlignment = .fill
```
ちょっと大きすぎますが、一旦このままで。
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480691/4d4684fe-cdd0-7e96-5404-d1923192b48a.png">
##ボタンを丸くする
いよいよボタンを丸くします。
値はボタンのサイズ/2で設定すると丸くなります。

```swift
// ボタンを丸くする(サイズ/2で設定)
customButton.layer.cornerRadius = 50
```
画像がはみ出ていますが、丸くなりました。
先程Aligmentの設定をしましたが、さすがに`cornerRadius`を考慮して自動的に小さくはならないですね。
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480691/33475524-6d69-9fc2-feee-69f54b15ada2.png">
##画像の大きさを調整する
画像を小さくするために、`UIEdgeInsets`を追加します。
ボタンと画像の間にマージンを入れているようなもので、値が大きくなる程間隔が大きくなり、画像が小さくなります。

```swift
// 画像を縮小する(マージンのようなもの)
customButton.imageEdgeInsets = UIEdgeInsets(top: 30, left: 30, bottom: 30, right: 30)
```
画像の大きさが良い感じなりました。
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480691/2a7819fd-a2e0-8089-ed2f-b29e937980e6.png">
##ボタンに影をつける
最後にボタンを立体的に見せるために、影をつけます。
ボタンの背景色は白くします。

```swift
// ボタンの背景色を白に戻す
customButton.backgroundColor = UIColor.white
// 影の色
customButton.layer.shadowColor = UIColor.black.cgColor
// 影のぼかし？
customButton.layer.shadowRadius = 3
// 影の位置
customButton.layer.shadowOffset = CGSize(width: 1.5, height: 1.5)
// 影の濃さ
customButton.layer.shadowOpacity = 0.3
```
立体的で丸いボタンのできあがりです。
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480691/abab6986-6067-ee88-4537-ef0eef0805ed.png">
##補足：影のプロパティについて
今回設定したshadowのプロパティが何なのかそれぞれみていきます。
###影の色(shadowColor)、影の濃さ(shadowOpacity)
影の色と濃さはそのまんまです。
例えば、赤色でもっと濃くしてみます。

```swift
// 影の色
customButton.layer.shadowColor = UIColor.red.cgColor
// 影の濃さ
customButton.layer.shadowOpacity = 0.9
```
こんな感じです。
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480691/b854129b-e583-0dab-409d-72aa604082bd.png">
###影のぼかし？(shadowRadius)
続いて影のぼかし？というのでしょうか。
値を大きすると影が広がります。

```swift
// 影のぼかし？
customButton.layer.shadowRadius = 50
```
影が大分広がりました。
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480691/2cb66c55-3da1-9b5b-33b1-8fa78fab24e2.png">
###影の位置(shadowOffset)
最後に影の位置についてです。
値を大きくすると影が離れていきます。

```swift
// 影の位置
customButton.layer.shadowOffset = CGSize(width: 30, height: 30)
```
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480691/17e1fba7-61c9-489c-a3f9-4a495f57cbba.png">
影がボタンから大きく離れました.

##おわり
最後まで読んで頂きありがとうございます。
不備や補足などありましたら教えて頂けますと助かります。