【iOS】UIButtonにボーダーラインを引けるようにする

4辺に線を引けるようにしたUIButtonを紹介します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272677/efeda073-cc43-a440-c4d1-5caddf673d5d.png)

色と太さのほか、各辺の開始点・終了点のオフセットを指定できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272677/e631136c-ccc7-700a-0f01-96558c7c0de7.png)

画面回転もOK。（わかりづらい）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272677/ad5245b5-2392-7192-d1b9-c7d79dc86ebb.png)

縦に並べる時にけっこう良い。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272677/d719f404-e3de-0b2f-34cc-40b7b35b7aa2.png)
# コード
```swift
import UIKit

class BorderedButton: UIButton {
    private var topBorder: CALayer = CALayer()
    private var bottomBorder: CALayer = CALayer()
    private var leftBorder: CALayer = CALayer()
    private var rightBorder: CALayer = CALayer()
    private var layers: [CALayer] = []
    private var widths: [CGFloat] = [0, 0, 0, 0]
    private var startOffsets: [CGFloat] = [0, 0, 0, 0]
    private var endOffsets: [CGFloat] = [0, 0, 0, 0]
    

    override init(frame: CGRect) {
        super.init(frame: frame)
        setUp()
    }
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setUp()
    }
    private func setUp() {
        layers = [topBorder, bottomBorder, leftBorder, rightBorder]
        layers.forEach {
            $0.backgroundColor = UIColor(red: 221/255, green: 221/255, blue: 221/255, alpha: 0.92).cgColor
            self.layer.addSublayer($0)
        }
    }
    func setBorderColor(_ color: UIColor) {
        layers.forEach {
            $0.backgroundColor = color.cgColor
        }
    }
    func setTopBorder(width: CGFloat, startOffset: CGFloat, endOffset: CGFloat) {
        widths[0] = width
        startOffsets[0] = startOffset
        endOffsets[0] = endOffset
    }
    func setBottomBorder(width: CGFloat, startOffset: CGFloat, endOffset: CGFloat) {
        widths[1] = width
        startOffsets[1] = startOffset
        endOffsets[1] = endOffset
    }
    func setLeftBorder(width: CGFloat, startOffset: CGFloat, endOffset: CGFloat) {
        widths[2] = width
        startOffsets[2] = startOffset
        endOffsets[2] = endOffset
    }
    func setRightBorder(width: CGFloat, startOffset: CGFloat, endOffset: CGFloat) {
        widths[3] = width
        startOffsets[3] = startOffset
        endOffsets[3] = endOffset
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        layoutBorderFrame()
    }
    private func layoutBorderFrame() {
        topBorder.frame = CGRect(x: startOffsets[0], y: 0, width: self.frame.width - (startOffsets[0] + endOffsets[0]), height: widths[0])
        bottomBorder.frame = CGRect(x: startOffsets[1], y: self.frame.height - widths[1], width: self.frame.width - (startOffsets[1] + endOffsets[1]), height: widths[1])
        leftBorder.frame = CGRect(x: 0, y: startOffsets[2], width: widths[2], height: self.frame.height - (startOffsets[2] + endOffsets[2]))
        rightBorder.frame = CGRect(x: self.frame.width - widths[3], y: startOffsets[3], width: widths[3], height: self.frame.height - (startOffsets[3] + endOffsets[3]))
    }
}
```

# 使い方
以下のように太さ・オフセット・色を指定できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272677/93243457-5728-a37f-90dc-3b0fb27cc090.png)

```swift
let button = BorderedButton()
button.setTopBorder(width: 4, startOffset: 240, endOffset: 0)
button.setRightBorder(width: 36, startOffset: 0, endOffset: 0)
button.setLeftBorder(width: 36, startOffset: 0, endOffset: 0)
button.setBottomBorder(width: 4, startOffset: 0, endOffset: 240)
button.setBorderColor(UIColor.orange)
button.setTitle("Hello Bordered Button", for: .normal)
button.setTitleColor(.black, for: .normal)
```