Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 沿直线路径和拐角拖动UIView_Objective C_Ios_Cocoa Touch - Fatal编程技术网

Objective c 沿直线路径和拐角拖动UIView

Objective c 沿直线路径和拐角拖动UIView,objective-c,ios,cocoa-touch,Objective C,Ios,Cocoa Touch,我想要的是一个汽车变速器的模式。它由大约9条90度角的直线组成,我需要用户拖动UIView 我的第一种方法是检查视图中心的坐标,如果满足某些条件,则适当地启用/禁用x/y。这导致了一个很长很复杂的if语句,需要维护。在大多数情况下,它是有效的——有时它会卡住,但我知道我需要做些什么来修复它 我的第二个想法是在我的路径周围建立一个非常简单的矩形集合,中间有一个足够宽的空间,允许一个正方形,我会锚定到我想要移动的视图。然后,我将能够使用碰撞检测来保持沿路径的视图。这似乎适用于非常基本的块状路径,但不

我想要的是一个汽车变速器的模式。它由大约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]];
}
//我们不使用if-else的原因是,如果x和y在拐角处,我们希望同时允许它们移动。
如果(knob.center.x>=218&&knob.center.x240){
平移.x=240-旋钮.center.x;
}
}
如果(knob.center.x==240&&knob.center.y>=140&&knob.center.y 230){translation.y=230-knob.center.y;}
}
如果(knob.center.x>=224&&knob.center.x240){translation.x=240-knob.center.x;}
} 
如果(knob.center.x==224&&knob.center.y>=230&&knob.center.y285){translation.y=285-knob.center.y;}
} 
如果(knob.center.x>=205&&knob.center.x224){translation.x=224-knob.center.x;}
}  
如果(knob.center.x==205&&knob.center.y>=285&&knob.center.y337){translation.y=337-knob.center.y;}
} 
如果(knob.center.x>=133&&knob.center.x205){translation.x=205-knob.center.x;}
}        
if(canMoveX){
[piece setCenter:CGPointMake([piece center].x+translation.x[piece center].y)];
[手势设置翻译:CGPointZero-inView:[piece superview]];
}
如果(可以移动){
[piece setCenter:CGPointMake([piece center].x[piece center].y+translation.y)];
[手势设置翻译:CGPointZero-inView:[piece superview]];
}

是的,你可以在没有太多这些的情况下制作动画,如果..否则,你将不得不实现核心动画的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"];
这段代码仅供参考,给你一个想法,对于实际的程序你必须给出坐标

根据我们的讨论:-

您可以通过从用户获取对象上的接触点(如您已定义的路径)来实现上述代码上的逻辑。您可以实现UIgestureRecognitor,甚至可以实现UItouch的TouchsBegind或TouchsEnded,以获取类似拖动的事件,然后在用户仍在触摸else调用时设置动画

[yourView.layer removeAllAnimations]; 

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

我无法找到完全解决问题的解决方案,因此我被迫使用条件和点。如果有人有更好的解决方案,我会很高兴在将来将其标记为正确的。

这适用于沿路径设置视图的动画,但是我需要用户能够沿路径拖动。我知道你要做什么-这是有意义的,但我担心它会从本质上删除用户的控制。我还应该指定移动应该是双向的,允许用户根据拖动的位置沿路径向前或向后移动。不过,我会仔细考虑一下你的想法,看看我是否可以使用正确的拖动功能。