churabou / iOS-develop-blog

0 stars 0 forks source link

[下書き] #7

Open churabou opened 6 years ago

churabou commented 6 years ago

画像編集アプリでテキストを合成する際に使うラベルをオリジナルで作成した。

今回作成したラベルはこちら。


gif で adobeのやつ

右下の丸い部分で拡大、回転するやつ。 最初は変なUIとか思ったのですが、いろんなアプリで似たような感じだったので・・

完成品


自分のやつ

一応使える形で出しときます

使い方


let label = label.setUp(parent: )

まあソース自体も200行程度なので

まずViewの構成ですがこちらボーダーをつけて。

UILabelの四隅に丸いViewを追加するだけだと思ったのですが、 そうすると丸のタップ可能領域が少しということに気づき、 めんどくさいので大きいUIViewに丸とラベルを追加することにした。

引っ張った時のジェスチャー

--- .swift


実装項目を整理すると

回転はatan2というタンジェントの逆関数を使うと、中心からの角度が取得できるので、 CGAffinTransfromでそのまま回転させてあげるだけ。

大きさは中心からの距離を使ってスケールを計算することで ラベルの大きさを大きくできる。

ここはなんかもう動いてるからいいかなっていう感じなんですけど、

スケールがわかる -> labelのsizeを修正 -> fontを更新

が無難なんでしょうけど 本来はラベルを大きくしたいのであってフォントをあげたいので

スケール -> フォント -> labelのサイズを修正

とした。

そもそもboundsがN倍になればFontSizeがN倍にはならないと思うけど、 綺麗に動いてたので()

ちなみに SizeToFitとか便利メソッドを多様した。 普通に複数行でも動いたのでOK

UILabelのpanGesutureで移動。

これはtransformを無視できるのでboundsを使う。 場合によっては親Viewの外に出したくない場合もあると思いますが、今回は。

churabou commented 6 years ago

Viewのlayerは特別だなと思ったのと、 1年以上経つけど、CALayerの座標を動かしてみたことがなかったので(CAAnimationで移動したことは有る)びっくりしたそのコードサンプル。

class ViewController: UIViewController {

    private lazy var panGesture: UIPanGestureRecognizer = {
        let p = UIPanGestureRecognizer(target: self, action: #selector(move))
        return p
    }()

    private var pre: CGPoint = .zero
    @objc func move(_ sender: UIPanGestureRecognizer) {
        let location = sender.location(in: view)
        if sender.state == .began {
            pre = location
        }
        let dx = location.x - pre.x
        let dy = location.y - pre.y

        pre = location

//viewはlayerのdelegate        
//        redView.center.x += dx
//        redView.center.y += dy    
        redView.layer.position.x += dx
        redView.layer.position.y += dy

        blueLayer.position.x += dx
        blueLayer.position.y += dy
    }

    private var redView = UIView()
    private var blueLayer = CALayer()

    override func viewDidLoad() {

        view.addGestureRecognizer(panGesture)

        redView.backgroundColor = .red
        redView.bounds.size = .equal(to: 150)
        redView.center = view.center
        view.addSubview(redView)

        blueLayer.backgroundColor = UIColor.blue.cgColor
        blueLayer.bounds.size = .equal(to: 150)
        blueLayer.position = view.center
        view.layer.addSublayer(blueLayer)
    }
}

中央に大きさ150の背景redのViewと背景blueのlayerを配置してみて、PanGestureで移動させてみると、 blueLayerはアニメーションした。通常のCALayerはアニメーションするのと、Viewのlayerは特別。


        CATransaction.begin()
        CATransaction.setAnimationDuration(0.0)

        blueLayer.position.x += dx
        blueLayer.position.y += dy

        CATransaction.commit()

止めるのは簡単だけど、なんでこんなことも知らなかったんだろう・・・