2017-01-10 12 views
0

質問をする前に、私はそうで検索しました:ビュー/レイヤーのベジェ曲線パスへの移動パスを制約する方法はありますか?

iPhone-Move UI Image view along a Bezier curve path

しかし、それは明示的な答えを与えていません。

私の要件は次のとおりです。ベジエパスとビュー(またはレイヤーがあればOK)があり、ビューにpan gestureを追加し、ビュー(またはレイヤー)の移動パスがベジェパス。

enter image description here

私のコードは以下の通りです:

MainDrawView.swift

import UIKit 

class MainDrawView: UIView { 


    // Only override draw() if you perform custom drawing. 
    // An empty implementation adversely affects performance during animation. 
    override func draw(_ rect: CGRect) { 
     // Drawing code 

     drawArc() 
    } 

    func drawArc() { 

     let context = UIGraphicsGetCurrentContext() 

     // set start point 
     context?.move(to: CGPoint.init(x: 0, y: 400)) 
     //draw curve 
     context?.addQuadCurve(to: CGPoint.init(x: 500, y: 250), control: CGPoint.init(x: UIScreen.main.bounds.size.width, y: 200)) 

     context?.strokePath() 

    } 
} 

ViewController.swift

import UIKit 

class ViewController: UIViewController { 

    @IBOutlet weak var clickButton: UIButton! 

    lazy var view1:UIView = { 

     let view: UIView = UIView.init(frame: CGRect.init(origin: CGPoint.init(x: 0, y: 0), size: CGSize.init(width: 10, height: 10))) 
     view.center = CGPoint.init(x: UIScreen.main.bounds.size.width/2.0, y: UIScreen.main.bounds.size.height/2.0) 
     view.backgroundColor = UIColor.red 

     return view 
    }() 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     initData() 
     initUI() 
    } 

    func initData() { 

    } 

    func initUI() { 

     self.clickButton.isHidden = true 

     // init the view 
     self.view.addSubview(self.view1) 
    } 

} 

編集-1

私の深い需要量は、私はビュー/レイヤーを移動pan guester使用する場合、ビューは、ベジェパスに移動しますです。

+0

CALayersになることはできますか?少なくとも私の意見では、UIViewsを達成するのはずっと簡単です。 1つのUIViewに複数のCALayerを含めることができます。これがうまくいくなら、私はそのトリックを行うかもしれないコードを持っています。 – dfd

+0

@dfd、ok、use CALayerも実装できます。 – aircraft

+0

@aircraft - あなたが正しくあなたが理解していることは、あなたがユーザーに 'UIPanGestureRecognizer'をアクティブにさせようとしていることです。そしてその更新として、四角形はパスに沿って移動しますか? – Pierce

答えて

1

ベジエ場合パスがオフラインになっていれば、ラインの傾きを見つけることができ、xまたはyの変化ごとにベジェパスの位置を計算することができます var y :Float = (slope * (xPos-previousCoord.x))+previousCoord.y; xPosが連続的に変化しています。同様に、uはxを見つけることができます。線分を含む閉じた形状の場合は、これを使用できます。

しかし、円のために必要ならば、デカルトを極座標に変換する必要があります。つまり、座標uから角度を見つけることができます。そして、その角度から、あなたはその角度を使って半径を持つので、それからデカルト座標を見つける必要があります。 enter image description here

θ= TAN-1(5/12)Uが主に3つの円の中心である座標を使用する必要が

は、二番目はあなたのタッチポイントであり、最後のものである(touchpoint.x 、centreofcircle.y)。二つの座標間の円を計算距離の中心から あなたがθ有し、円の半径は、次に、SIN(θ)

ドン×COS(θ)

Y = R×

X = Rを使用して点を見つけます円の半径の画像ではrを間違え、画像のrは三つの座標の斜辺です。タッチポイントでのxの変化ごとに計算する必要があります。

希望します。しかし、不規則な形のために私はどのように見つけるか分からない。

+0

私はサークルのためにそれを試して、それを拘束することができました。もし私があなたにコードを与えることができれば欲しい。 –

+0

私はあなたにコードを電子メールで送りました。それをチェックして、それについての明確化が必要なのかどうか教えてください。 –

+0

私にもメールコードplz –

0

おそらく計算をしなければならないようです。あなたがUIPanGestureRecognizerを処理するためにあなたの方法を設定するときは、パンのために戻ってベクトルを取得することができ、このような何か:

func panGestureRecognized(_ sender: UIPanGestureRecognizer) { 
    let vector:CGPoint = sender.translation(in: self.view) // Or use whatever view the UIPanGestureRecognizer was added to 
} 

その後、xとy軸に沿った動きを推定することを使用することができます。私はあなたがビューを動かしているパスの代数方程式を得ることから始めることをお勧めします。その線に沿ってビューを移動するには、UIPanGestureRecognizerの動きに対してその線に沿った点を計算し、その線に沿って計算された点を使用してビューの位置を更新する必要があります。

それはあなたが何をしようとしてのために働くだろうかどうかは知りませんが、パスに沿って、あなたのビューをアニメーション化しようとする場合、それは実際にはかなり簡単です:

let path = UIBezierPath() // This would be your custom path 

let animation = CAKeyframeAnimation(keyPath: "position") 
animation.path = path.cgPath 
animation.fillMode = kCAFillModeForwards 
animation.isRemovedOnCompletion = false  animation.repeatCount = 0 
animation.duration = 5.0 // However long you want 
animation.speed = 2 // However fast you want 
animation.calculationMode = kCAAnimationPaced 
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) 

animatingView.layer.add(animation, forKey: "moveAlongPath") 
関連する問題