我想要的模式是汽车中的变速器。它由大约9条90度角的直线组成,我需要用户拖动UIView。
我的第一种方法是检查视图中心的坐标,如果满足某些条件,则适当启用/禁用x / y。这导致了一个长期复杂的if语句,这将是一个混乱的维护。它在大多数情况下都有效 - 偶尔它会卡住,但我知道我需要做些什么来修复它。
我的第二个想法是在我的路径周围建立一个非常简单的矩形集合,中间的空间足够宽,以允许我将锚定到我想要移动的视图的方格。然后,我将能够使用碰撞检测来保持沿路径的视图。这似乎适用于非常基本的块状路径,但是对于更复杂的路径是不可行的。
还有其他方法可以达到我想要的效果吗?
顺便说一下,这是我对第一个场景的超级粗糙和低效的测试:// The reason we aren't using if else is because we want to allow both x and y movement if they are on a corner.
if(knob.center.x >= 218 && knob.center.x <= 240 && knob.center.y == 140) {
// First line
canMoveX = TRUE;
if(translation.x + knob.center.x < 218) {
translation.x = knob.center.x - 218;
}
else if(translation.x + knob.center.x > 240) {
translation.x = 240 - knob.center.x;
}
}
if(knob.center.x == 240 && knob.center.y >= 140 && knob.center.y <= 230) {
// Second Line
canMoveY = TRUE;
if(translation.y + knob.center.y < 140) { translation.y = knob.center.y - 140; }
else if(translation.y + knob.center.y > 230) { translation.y = 230 - knob.center.y; }
}
if(knob.center.x >= 224 && knob.center.x <= 240 && knob.center.y == 230) {
// Third Line
canMoveX = TRUE;
if(translation.x + knob.center.x < 224) { translation.x = knob.center.x - 224; }
else if(translation.x + knob.center.x > 240) { translation.x = 240 - knob.center.x; }
}
if(knob.center.x == 224 && knob.center.y >= 230 && knob.center.y <= 285) {
// Fourth Line
canMoveY = TRUE;
if(translation.y + knob.center.y < 230) { translation.y = knob.center.y - 230; }
else if(translation.y + knob.center.y > 285) { translation.y = 285 - knob.center.y; }
}
if(knob.center.x >= 205 && knob.center.x <= 224 && knob.center.y == 285) {
// Fifth Line
canMoveX = TRUE;
if(translation.x + knob.center.x < 205) { translation.x = knob.center.x - 205; }
else if(translation.x + knob.center.x > 224) { translation.x = 224 - knob.center.x; }
}
if(knob.center.x == 205 && knob.center.y >= 285 && knob.center.y <= 337) {
// Sixth Line
canMoveY = TRUE;
if(translation.y + knob.center.y < 285) { translation.y = knob.center.y - 285; }
else if(translation.y + knob.center.y > 337) { translation.y = 337 - knob.center.y; }
}
if(knob.center.x >= 133 && knob.center.x <= 205 && knob.center.y == 337) {
// Seventh Line
canMoveX = TRUE;
if(translation.x + knob.center.x < 133) { translation.x = knob.center.x - 133; }
else if(translation.x + knob.center.x > 205) { translation.x = 205 - knob.center.x; }
}
if(canMoveX) {
[piece setCenter:CGPointMake([piece center].x + translation.x, [piece center].y)];
[gesture setTranslation:CGPointZero inView:[piece superview]];
}
if(canMoveY) {
[piece setCenter:CGPointMake([piece center].x, [piece center].y + translation.y)];
[gesture setTranslation:CGPointZero inView:[piece superview]];
}
答案 0 :(得分:2)
是的,你可以在没有太多if..elses的情况下完成动画,你必须实现Core Animation的CAKeyFrameAnimation来描绘沿着brezier路径的纳米动画。
你必须定义一个路径并且为了查看我画了一条曲线来表示路径,然后是沿路径动画的对象,最后是动画: -
UIBezierPath *yourPath= [UIBezierPath bezierPath];
[yourPath moveToPoint:P(x, y)];
[yourPath addCurveToPoint:P(x1, y1) controlPoint1:P(x, y) controlPoint2:P(x, y)];
//You will have to use addCurveToPoint to add next turn.
CAShapeLayer *yourFollowPath= [CAShapeLayer layer];
yourFollowPath.path = yourPath.CGPath;
yourFollowPath.strokeColor = [UIColor redColor].CGColor;
yourFollowPath.fillColor = [UIColor blackColor].CGColor;
yourFollowPath.lineWidth = 50.0;
[self.view.layer addSublayer:yourFollowPath];
CALayer *moveObject= [CALayer layer];
moveObject.bounds = CGRectMake(x, y, width, height);
moveObject.position = P(objXPOs, objYPos);
moveObject.contents = (id)([UIImage imageNamed:@"YouImageOfObjectToMove"].CGImage);
[self.view.layer addSublayer:moveObject];
CAKeyframeAnimation *animate = [CAKeyframeAnimation animationWithKeyPath:@"Animating"];
animate .path = yourPath.CGPath;
animate .rotationMode = kCAAnimationRotateAuto;
animate .repeatCount = HUGE_VALF;
animate .duration = 11;
[moveObjectaddAnimation:animate forKey:@"gogogo"];
此代码仅供参考,为您提供一个想法,对于您必须提供坐标的实际程序。
根据我们的讨论: -
您可以通过在对象上获取用户的接触点(因为您已经定义了路径)来实现上述代码的逻辑。您可以实现UIGestureRecognizer,甚至可以触摸UI或touchesEnded UItouch来获取像事件一样的拖动然后动画如果用户还在触摸其他呼叫
[yourView.layer removeAllAnimations];
并获取最新的接触点,然后在触摸恢复时从该点创建另一个brezierPath。
答案 1 :(得分:0)
我无法找到完全解决问题的解决方案,所以我被迫使用条件和点数。如果有人有更好的解决方案,我将非常乐意将来标记为正确。