2016-05-19 22 views
-2

Wenn ich eine Zeile für ex erstellt habe. in der Abbildung als Verbindung A und B durch CAShapeLayer gezeigt und in der Mitte dieser Zeile habe ich eine UIView, die Pan-Geste integriert hat.Einschränkung der Schwenkbewegung auf 90 Grad

Wie kann man das UIView in eine bestimmte Richtung bewegen, die 90 Grad zu dieser Linie schafft, wie in der Abbildung gezeigt, zeigte die rote Linie die Richtung an, in der die UIView bewegt werden kann?

Der Mittelpunkt sollte beginnen, sich von der Mitte der Linie in die Richtung zu bewegen, die in der Abbildung dargestellt ist, die ich aktualisiert habe.

enter image description here

Antwort

3

Ich nehme an, Sie die Pfanne verarbeiten kann, und Sie können den Touch-Punkt gelangen. Was Sie wollen, ist die Projektion des Berührungspunktes auf die rote Linie zu berechnen und den UIView dort zu platzieren.

Die rote Linie steht senkrecht auf AB und besteht aus dem Mittelpunkt von 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:

Ihr Kommentar zeigt, dass die Nutzung dieses soulution für Sie nicht klar genug ist. Deshalb habe ich diese Idee in ein funktionierendes Beispiel eingebettet.

@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

vielleicht haben Sie meine Bedenken missverstanden, der Punkt sollte beginnen, sich von der Mitte der Linie zu bewegen, die Sie in der aktualisierten Frage sehen können. –

+0

auch, wenn der Benutzer den Mittelpunkt an einem bestimmten Punkt setzt und die Neupositionierung erneut beginnt, dann von dort nur nicht vom Mittelpunkt des Mittelpunkts aus beginnt. –