【Swift 5】線を引く。

みさなんこんちには、@Zhalen（ツァーレン）です。


この記事では、この画像の、
![IMG_0921.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540507/8ff81768-dc2a-3935-2505-9d9ff51e92be.png)
![IMG_0922.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540507/01574d66-1b08-df7b-0a81-41d7630d0d3d.jpeg)


このように任意の箇所に直線を引くメソッドを作ったので紹介します。

#Usage: 使い方

結論としては、このようにして使えるようになります。

```swift:UIViewController-viewDidLoad

<UIView>.drawLine(start: <CGPoint>, end: <CGPoint>, color: <UIcolor>, weight: <CGFloat>, rounded: <Bool>)
```

##まずはカスタムクラスを作りましょう

線を引くために、```BezierView```（ベジェビュー）という汎用的なカスタムクラスを作成して、それを使いまわします。

```swift

class BezierView: UIView {
    
    var start: CGPoint = .zero
    var end: CGPoint = .zero
    var weight: CGFloat = 2.0
    var color: UIColor = .gray
    var isRounded: Bool = true
 
    override init(frame: CGRect) {
        super.init(frame: frame);
        self.backgroundColor = UIColor.clear;
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func draw(_ rect: CGRect) {
        
        let line = UIBezierPath()
        line.move(to: start)
        line.addLine(to: end)
        line.close()
        color.setStroke()
        line.lineWidth = weight
        line.lineCapStyle = isRounded ? .round : .square
        line.stroke()
        self.isUserInteractionEnabled = false
    }
 
}
```

ここで

```swift

    var start: CGPoint = .zero
    var end: CGPoint = .zero
    var weight: CGFloat = 2.0
    var color: UIColor = .gray
    var isRounded: Bool = true
```

とありますがこれはデフォルト値で、それぞれ

```swift

    var start: CGPoint = //線の開始地点
    var end: CGPoint = //線の終了地点
    var weight: CGFloat = //線の太さ
    var color: UIColor = //線の色
    var isRounded: Bool = //角を丸くするかどうか
```

を表します。これらの情報を用いて、Extensionを作成します。

##こちらがそのExtensionです。

```swift

extension UIView {
    func drawLine(start: CGPoint, end: CGPoint, color: UIColor, weight: CGFloat, rounded: Bool) {
        let line: BezierView = BezierView(frame: CGRect(x: 0, y: 0, width: max(start.x , end.x)+weight, height: max(start.y, end.y)+weight))
        line.start = start
        line.end = end
        line.color = color
        line.weight = weight
        line.isRounded = rounded
        self.addSubview(line)
    }
}
```

こちらはシンプルなエクステンションを定義しましたが、より一般的に定義したい場合は、複数の点を用いて

```swift

extension UIView {
    func drawLine(points: [CGPoint], color: UIColor, weight: CGFloat, rounded: Bool) {
        guard points.count >= 2 else { fatalError("Line is not drawable because points are less than 2") }
        for i in 0..<points.count-1 {
            self.drawLine(start: points[i], end: points[i+1], color: color, weight: weight, rounded: rounded)
        }
    }
}
```

のようにすることも可能です。実際に上の画像での折れ線はこの```points```付きのやつを使っています。書く分には損はないので、念のためこれも書いておきましょう。



#コピペ用コード全文です。

```swift

class BezierView: UIView {

    var start: CGPoint = .zero
    var end: CGPoint = .zero
    var weight: CGFloat = 2.0
    var color: UIColor = .gray
    var isRounded: Bool = true

    override init(frame: CGRect) {
        super.init(frame: frame);
        self.backgroundColor = UIColor.clear;
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func draw(_ rect: CGRect) {

        let line = UIBezierPath()
        line.move(to: start)
        line.addLine(to: end)
        line.close()
        color.setStroke()
        line.lineWidth = weight
        line.lineCapStyle = isRounded ? .round : .square
        line.stroke()
        self.isUserInteractionEnabled = false
    }

}
extension UIView {
    func drawLine(start: CGPoint, end: CGPoint, color: UIColor, weight: CGFloat, rounded: Bool) {
        let line: BezierView = BezierView(frame: CGRect(x: 0, y: 0, width: max(start.x , end.x)+weight, height: max(start.y, end.y)+weight))
        line.start = start
        line.end = end
        line.color = color
        line.weight = weight
        line.isRounded = rounded
        self.addSubview(line)
    }
    func drawLine(points: [CGPoint], color: UIColor, weight: CGFloat, rounded: Bool) {
        guard points.count >= 2 else { fatalError("Line is not drawable because points are less than 2") }
        for i in 0..<points.count-1 {
            self.drawLine(start: points[i], end: points[i+1], color: color, weight: weight, rounded: rounded)
        }
    }
}
```


#宣伝です
![スクリーンショット 2020-12-30 17.42.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540507/32438993-4e40-e9ae-474f-718d6732c5fc.png)


つい先日、アンケート特化型SNS「<b>Vote.</b>」をリリースしました！

このアプリは、何かの選択で迷った時・悩んだ時、それだけでなく企業のA/Bテストやテストマーケティングなど実用的な面でも役に立つアプリです！　非常にデザインも洗練されており、誰でも気軽にアンケートや投票を取ることができます。

#####インストールはこちらから：https://apps.apple.com/us/app/vote/id1542436046