2016-05-19 4 views
-2

元の行を作成した場合。図に示すようにAとBをCAShapeLayerに接続し、その行の中央にはUIViewがあり、その中にパンジェスチャが組み込まれています。パンのジェスチャーを90度に移動制限する

UIViewを図のようにその線に対して90度の方向に移動させるには、UIViewの方向を赤い線で指示してください。

中点は、更新した図の方向に線の中心から移動を開始する必要があります。

enter image description here

答えて

3

私はあなたがパンを扱うことができると仮定して、あなたはタッチポイントを取得することができます。あなたがしたいのは、赤い線にタッチポイントの投影を計算し、そこにUIViewを配置することです。

赤い線はABに垂直で、ABの中間点になります。

// 
//when the pan gesture recognizer reports state change event 

/*you have 
    CGPoint A; 
    CGPoint B; 
    CGPoint T; //touch point 
*/ 

//midpoint 
CGPoint M = {(A.x+B.x)/2, (A.y+B.y)/2}; 

//AB distance 
CGFloat distAB = sqrtf(powf(B.x-A.x, 2) + powf(B.y-A.y, 2)); 

//direction of the red line with unit length 
CGVector v = {(B.y-A.y)/distAB, -(B.x-A.x)/distAB}; 

// vector from midpoint to touch point 
CGVector MT = {T.x-M.x, T.y-M.y}; 

// dot product of v and MT 
// which is the signed distance of the projected point from M 
CGFloat c = v.dx*MT.dx + v.dy*MT.dy; 

// projected point is M + c*v 
CGPoint projectedPoint = {M.x + c*v.dx, M.y + c*v.dy}; 

//TODO: set the center of the moving UIView to projectedPoint 

UPDATE:

コメントがこのsoulutionの利用はあなたのために十分に明確ではないことを、明らかになりました。したがって、私はこの考え方を実際の例に埋め込んでいます。

@interface ViewController() 

@end 

@implementation ViewController { 
    CGPoint A; 
    CGPoint B; 
    CGPoint M; //midpoint of AB 
    CGVector v; //direction of the red line with unit length 

    UIView* pointMover; 
} 

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    A = CGPointMake(50,50); 
    B = CGPointMake(300,200); 

    M = CGPointMake((A.x+B.x)/2, (A.y+B.y)/2); 
    CGFloat distAB = sqrtf(powf(B.x-A.x, 2) + powf(B.y-A.y, 2)); 
    v = CGVectorMake((B.y-A.y)/distAB, -(B.x-A.x)/distAB); 

    pointMover = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 44, 44)]; 
    pointMover.center = M; 
    pointMover.backgroundColor = [UIColor blueColor]; 
    pointMover.layer.cornerRadius = 22.0f; 
    [self.view addSubview:pointMover]; 

    UIPanGestureRecognizer* panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)]; 
    [pointMover addGestureRecognizer:panRecognizer]; 

    UIBezierPath* blackLinePath = [UIBezierPath bezierPath]; 
    [blackLinePath moveToPoint:A]; 
    [blackLinePath addLineToPoint:B]; 
    CAShapeLayer *blackLineLayer = [CAShapeLayer layer]; 
    blackLineLayer.path = [blackLinePath CGPath]; 
    blackLineLayer.strokeColor = [[UIColor blackColor] CGColor]; 
    blackLineLayer.lineWidth = 2.0; 
    [self.view.layer addSublayer:blackLineLayer]; 


} 

- (void)handlePan:(UIPanGestureRecognizer*)recognizer { 

    //touch point 
    CGPoint T = [recognizer locationInView:self.view]; 

    // vector from midpoint to touch point 
    CGVector MT = {T.x-M.x, T.y-M.y}; 

    // dot product of v and MT 
    CGFloat c = v.dx*MT.dx + v.dy*MT.dy; 

    // projected point is M + c*v 
    CGPoint projectedPoint = {M.x + c*v.dx, M.y + c*v.dy}; 

    pointMover.center = projectedPoint; 
} 


@end 
+0

あなたは私の懸念を誤解しているかもしれませんが、ポイントは、更新された質問で見ることができる行の中央から移動を開始する必要があります。 –

+0

また、ユーザーがある点に中間点を置き、再び位置を変更した場合は、中間点の中心からではなく、そこから開始します。 –

関連する問題