-2
元の行を作成した場合。図に示すようにAとBをCAShapeLayer
に接続し、その行の中央にはUIView
があり、その中にパンジェスチャが組み込まれています。パンのジェスチャーを90度に移動制限する
UIView
を図のようにその線に対して90度の方向に移動させるには、UIView
の方向を赤い線で指示してください。
中点は、更新した図の方向に線の中心から移動を開始する必要があります。
元の行を作成した場合。図に示すようにAとBをCAShapeLayer
に接続し、その行の中央にはUIView
があり、その中にパンジェスチャが組み込まれています。パンのジェスチャーを90度に移動制限する
UIView
を図のようにその線に対して90度の方向に移動させるには、UIView
の方向を赤い線で指示してください。
中点は、更新した図の方向に線の中心から移動を開始する必要があります。
私はあなたがパンを扱うことができると仮定して、あなたはタッチポイントを取得することができます。あなたがしたいのは、赤い線にタッチポイントの投影を計算し、そこに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
あなたは私の懸念を誤解しているかもしれませんが、ポイントは、更新された質問で見ることができる行の中央から移動を開始する必要があります。 –
また、ユーザーがある点に中間点を置き、再び位置を変更した場合は、中間点の中心からではなく、そこから開始します。 –