IB上で範囲の確認ができるUIButtonのタップエリアを拡大する実装

# はじめに
こんにちは:leaves:
少し前にボタンの大きさやデザインを変えずにタップ領域だけを広くする事について悩んだ際に[【iOS】UIButtonのタップ領域だけを拡大する](http://qiita.com/KokiEnomoto/items/264f26bfa92d06b1996e)という素晴らしい記事を拝見し、実装することができたので共有してみたいと思います。今回は**IB上での拡大した領域の確認**や**値の設定**が出来るようにしてみました。

![screen.png](https://qiita-image-store.s3.amazonaws.com/0/128250/ffbd7371-8390-f5d4-09df-95c356a01a70.png)

# ソースコード
クラス名や関数名など、ご自由に変更してください

```TapAreaExpandButton.swift
import UIKit

@IBDesignable class TapAreaExpandButton: UIButton {
    
    @IBInspectable var dotLineColor: UIColor = .black
    
    @IBInspectable var top: CGFloat {
        get { return expandEdgeInsets.top }
        set { expandEdgeInsets.top = newValue }
    }
    @IBInspectable var left: CGFloat {
        get { return expandEdgeInsets.left }
        set { expandEdgeInsets.left = newValue }
    }
    @IBInspectable var bottom: CGFloat {
        get { return expandEdgeInsets.bottom }
        set { expandEdgeInsets.bottom = newValue }
    }
    @IBInspectable var right: CGFloat {
        get { return expandEdgeInsets.right }
        set { expandEdgeInsets.right = newValue }
    }
    
    var expandEdgeInsets = UIEdgeInsets.zero
    
    var expandedBounds: CGRect {
        return CGRect(x: bounds.origin.x - expandEdgeInsets.left,
                      y: bounds.origin.y - expandEdgeInsets.top,
                      width: bounds.size.width + expandEdgeInsets.left + expandEdgeInsets.right,
                      height: bounds.size.height + expandEdgeInsets.top + expandEdgeInsets.bottom)
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
    
    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
        return expandedBounds.contains(point)
    }
    
    //IB上でのみ実行される処理
    override func prepareForInterfaceBuilder() {
        if expandEdgeInsets == UIEdgeInsets.zero { return }
        let tapGuideView = UIView(frame: expandedBounds)
        let lineLayer = CAShapeLayer()
        lineLayer.frame = tapGuideView.bounds
        lineLayer.strokeColor = dotLineColor.cgColor
        lineLayer.lineWidth = 1
        lineLayer.lineDashPattern = [2, 2]
        lineLayer.fillColor = nil
        lineLayer.path = UIBezierPath(rect: lineLayer.frame).cgPath
        tapGuideView.isUserInteractionEnabled = false
        tapGuideView.backgroundColor = UIColor.clear
        tapGuideView.isHidden = false
        tapGuideView.layer.addSublayer(lineLayer)
        addSubview(tapGuideView)
    }
}
```

# 実装について
- UIButtonに対して**点線**を入れても表示するサイズが足りないため、
**Interface Builder**上で実行される`prepareForInterfaceBuilder()`で表示用の**UIView**を作成しています。

![IB.png](https://qiita-image-store.s3.amazonaws.com/0/128250/688607af-27d0-795f-6611-66e09fec457f.png)![Run.png](https://qiita-image-store.s3.amazonaws.com/0/128250/1ae57088-60e4-c079-bec9-439b0c7945ff.png)


- `@IBInspectable`は**UIEdgeInsets**に対応されていないため、CGFloatを用いて間接的に値を設定しています

<img width="241" alt="value.png" src="https://qiita-image-store.s3.amazonaws.com/0/128250/86d0101e-1db6-75ef-291c-0c5fc588ac69.png">

# 参考にさせていただいた記事
- [@IBDesignableと@IBInspectableを使ってグラデーション可能なカスタムViewを作ってみた Qiita](http://qiita.com/motokiee/items/762f42c22ae70c689cb9)

- [[iOS] touchイベントを制御する](http://qiita.com/edo_m18/items/b1528f7aea0e06fbe6b4)

- [【iOS】UIButtonのタップ領域だけを拡大する](http://qiita.com/KokiEnomoto/items/264f26bfa92d06b1996e)

見て頂いてありがとうございます。