我要使用的模式是汽车中的变速杆。它由90度角的大约9条直线组成,我需要用户拖动UIView才能沿着。

我的第一种方法是检查视图中心的坐标,如果满足某些条件,则适当地启用/禁用x / y。这导致了一个漫长的if语句,该语句很难维护。在大多数情况下,它都能正常工作-偶尔会卡住,但是我知道我需要做些什么来修复它。

我的第二个想法是在路径周围构建一个非常简单的矩形集合,在中间留出一个足够宽的空间,以允许一个正方形固定在我要移动的视图上。然后,我将能够使用碰撞检测使视图沿路径移动。这似乎适用于非常基本的块状路径,但使用更复杂的路径则不可行。

还有其他方法可以达到我想要的效果吗?

顺便说一句,这是我对第一种情况的 super 粗略和低效的测试:

//  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]];
}

最佳答案

是的,您可以在没有很多if..elses的情况下进行动画处理,您将必须实现Core Animation的CAKeyFrameAnimation才能沿着更轻巧的路径描绘一个动画。

您将必须定义一条路径,并且为了查看,我绘制了一条曲线来表示该路径,然后沿着该路径对其进行动画处理的对象以及最后的动画:-

     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甚至UItouch的touchesBegan或touchesEnded来获取类似拖动的事件,然后对它们进行动画处理用户仍在触摸其他电话
[yourView.layer removeAllAnimations];

并获取最新的接触点,然后在恢复接触时从该点创建另一个brezierPath。

关于objective-c - 沿直线路径和角落拖动UIView,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10634921/

10-11 22:32
查看更多