【Swift3】UIBezierPathで卵型を書こう【CAShapeLayer】

どもも。CAShapeLayerで図形を描こうという記事です。

以前、【Swift 3】CALayerを用いて図形を移動・拡大縮小してみた【CALayer】という記事を書いたのですが、その時は直線と丸と四角といった図形の書き方をちょろっと紹介しました。

 

今回はCAShapeLayerにUIBezierPathを用いて卵型を描いていこうと思います。

曲線を扱うのは初めてだったので、なかなか手こずりました。

CALayerとCAShapeLayerのお話は以前の記事を読んでくださいな〜。

 

卵型を書こう!

まずは卵型を描く部分の全体を見せてから部分の説明をしていこうと思います。

    override func viewDidLoad() {
        super.viewDidLoad()
        let width = view.frame.width
        let height = view.frame.height

        //卵を描くレイヤー
        let egg = CAShapeLayer()
        egg.strokeColor = UIColor.yellow.cgColor  /* 輪郭線の色 */
        egg.lineWidth = 10.0                      /* 輪郭線の太さ */
        egg.fillColor = UIColor.blue.cgColor      /* 塗りの色 */
        
        //卵を描くライン
        let line = UIBezierPath()
        
        //実際の点
        let posA:CGPoint = CGPoint(x:width / 6,y:height * 2 / 3)
        let posB:CGPoint = CGPoint(x:width * 5 / 6,y:height * 2 / 3)
        
        //コントロールポイント
        let controlA:CGPoint = CGPoint(x:0,y:height)
        let controlB:CGPoint = CGPoint(x:width,y:height)
        let controlC:CGPoint = CGPoint(x:width / 2,y:0)
        
        //卵を描く
        line.move(to: posA)
        line.addCurve(to: posB, controlPoint1: controlA, controlPoint2: controlB)
        line.addQuadCurve(to:posA,controlPoint:controlC)
        
        line.close()
        egg.path = line.cgPath
        self.view.layer.addSublayer(egg)
    }

 

実行結果

 

view上にCAShapeLayerをのせて卵を描いています。

線の太さが1.0だと黄色の輪郭線が全然見えないですね(´・ω・`)

 

addCurveとaddQuadCurve

今回の肝はこの2つ。

実際に卵を書いている部分はこの部分

//卵を描く
line.move(to: posA)
line.addCurve(to: posB, controlPoint1: controlA, controlPoint2: controlB)  /* ① */
line.addQuadCurve(to:posA,controlPoint:controlC)                           /* ② */
line.close()

 

全部で5つの座標を使っているのですが、実際にはposAとposBを2回に分けて結んでるだけです。

面倒なのがコントロールポイントというやつです。

addCurveとaddQuadCurveの違いは見てわかるようにコントロールポイントが1つか2つかです。

 

addCurve

①のaddCurveはコントロールポイントが2つあります。

始点は1つ前の終点で、今回はposAが始点になります。

始点側のcontrolPointがcontrolPoint1

終点側(to)のcontrolPointがcontrolPoint2

となります。

今回はつなぎ目が滑らかになるようにそれぞれ外側に配置し、controlAとcontrolBは卵の真ん中を軸とした線対称の位置にしました。

 

addQuadCurve

addQuadCurveはコントロールポイントが1つになります。

 

こちらも始点は1つ前の終点になります。今回はposBが始点になります。

to:が行き先のposA

controlPointが卵の中心のy軸上の少し離れたところにしています。

y座標を変更すれば卵の頭のカーブのきつさが変更されます。

 

最後にline.close()で線を閉じておきます。

コントロールポイントの位置がなかなか難しくて思った形にするのが大変です。

 

別の方法

addQuadCurveだけで乗り切ろうとしたらこんな感じになりました。

line.move(to: CGPoint(x:width / 6,y:height * 2 / 3))
line.addQuadCurve(to:CGPoint(x:width / 2,y:height),controlPoint:CGPoint(x:0,y:height))
line.addQuadCurve(to:CGPoint(x:width * 5 / 6,y:height * 2 / 3),controlPoint:CGPoint(x:width,y:height))
line.addQuadCurve(to:CGPoint(x:width / 6,y:height * 2 / 3),controlPoint:CGPoint(x:width / 2,y:0))

 

実行結果はこんな感じ

 

ちょっとごちゃごちゃして見づらいですが、3点で結んでいます。

 

作りたい形に合わせて上手いこと使い分けたいですね。

UIImageで画像を用意するよりCALayerを用いるほうが処理が軽くなる(はず)なので簡単な図形は作れるようになりたいです。

 

画質がちょっと悪くて申し訳ないです(´・ω・`)

それではでは

 

 

流石に中国語は読めないです。画像を参考にさせていただきました。(google画像検索より)

2018/04/14追記
Swift4(Xcode9.3)での動作確認済みです〜
コメントは認証制です。詳しくは下記の注意をお読みください。お気軽にコメントお願いします!

Write a Comment

コメント時の注意

「Twitter」「Facebook」「Google+」「WordPress」のいずれかのアカウントをお持ちの方は各アカウントと連携することでコメントできます。 コメントしたことはSNSに流れませんので、アカウントをお持ちの方はこちらの方法でコメントを投稿して下さると嬉しいです。 アカウントをお持ちでない方はメールアドレスで投稿することができます。 初回コメント時は承認後に表示されます。

Related Memo...

UINavigationController + UIScrollView の組み合わせで使っている時に謎の余白ができる時

UINavigationController + UIScrollView の組み合わせで使っていて、UIScrollView 上に AutoLayout で上下左右0で View を設置しているのに、30px程度上にずれてしまうとき。

`navigationController.navigationBar.isTranslucent = false` にすると直るかもしれない。

ScrollView上のコンテンツとNavigationBarの重なっているところが透過していたら多分これで直せるはず。

通常のターゲットではちゃんと動いているのに、iOSSnapshotTestCase を用いたテストでだけこの対応が必要なのよくわからないけれど。。。

iOS

UITableView.RowAnimation の .none はアニメーションするよ

UITableView.RowAnimation の .none はアニメーションがnoneなわけじゃなく、デフォルトの設定を使うよという意味らしい。

The inserted or deleted rows use the default animations.

なのでアニメーションしちゃう。今更の気づき。

 

iOS

記事を書くほどでもないけれどメモっておきたいこと

テスト投稿。

例えばiphone7 の画面サイズ

750 × 1334
半分375 × 667

iOS
more