限制平移手势移动到90度 [英] Restricting pan gesture to move to 90 degree

查看:84
本文介绍了限制平移手势移动到90度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我为ex创建了一行.如图所示为通过CAShapeLayer连接A和B,在该行的中心,我有一个UIView,其中集成了平移手势.

If I have created a line for ex. shown in the figure as connecting A and B through CAShapeLayer and in that line's centre I have a UIView which has pan gesture integrated in it.

如何使UIView移动到与该线成90度的某个方向,如图所示,红线表示UIView可以移动的方向?

How to make that UIView to move to a certain direction that creates 90 degrees to that line as shown in the figure the red line indicated the direction that the UIView can be moved?

中点应从线的中心开始朝我更新的图中所示的方向移动.

The mid-point should start moving from the centre of the line, in the direction that shown in the figure that I have updated.

推荐答案

我认为您可以处理平底锅,并且能够获得接触点.您想要的是计算触摸点到红线的投影并将UIView放置在其中.

I assume you can handle the pan, and you are able to get the touch point. What you want is to calculate the projection of the touch point to the red line and place the UIView there.

红线垂直于AB,由AB的中点组成.

The red line is perpendicular to AB and consist the midpoint of 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

更新:

您的评论显示,这种解决方案的利用对您来说还不够清楚.因此,我将这个想法嵌入了一个可行的例子中.

Your comment reveals, that the utilization of this soulution is not clear enough for you. Therefore I have embedded this idea into a working example.

@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

这篇关于限制平移手势移动到90度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆