2012-05-17 3 views
1

Образец, который я собираюсь сделать, это механизм переключения передач в автомобиле. Он состоит из приблизительно 9 прямых линий под углом 90 градусов, которые мне нужны, чтобы пользователь перетащил UIView.Перетащите UIView по прямому пути и углам

Мой первый подход состоял в том, чтобы проверить координаты центра обзора, и если выполнены определенные условия, включите/отключите x/y соответствующим образом. Это привело к длинному сложному заявлению, которое будет бесполезным для поддержания. Он работает, по большей части - иногда он застревает, но я знаю, что мне нужно сделать, чтобы исправить это.

Моей второй идеей было бы создание очень простой коллекции прямоугольников вокруг моего пути с пространством в середине, достаточно широким, чтобы позволить квадрат, который я бы привязал к виду, которое я хочу переместить. Затем я мог бы использовать обнаружение столкновений, чтобы сохранить вид вдоль пути. Похоже, что это будет работать для самых простых блочных путей, но не будет осуществимо с более сложным путем.

Есть ли другие способы достижения желаемого эффекта?

Кстати, вот мой супер грубый и неэффективный тест для первого сценария:

// 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, Вы должны реализовать CAKeyFrameAnimation от Core Animation чтобы изобразить намагничивание вдоль пути брезента.

Вы должны определить путь и для просмотра я нарисовал кривую, чтобы обозначить путь, а затем объект, который будет анимированный вдоль пути и, наконец, анимация: -

 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"]; 

Этот код является просто для ссылки, чтобы дать вам представление, для реальной программы вам нужно будет дать координаты.

Согласно нашей дискуссии: -

Вы можете реализовать вам логику над кодом, указанным выше, получив от точек соприкосновения пользователя на объекте (как вы aleady определенного пути) .Вы может реализовать UIGestureRecognizer или даже touchesBegan или touchesEnded из UITouch, чтобы получить сопротивление, как событие, а затем анимировать, если пользователь все еще трогательная еще называют

[yourView.layer removeAllAnimations]; 

и получить последнюю TouchPoint, а затем создать еще один brezierPath с этой точки, если прикосновение возобновляется.

+0

Это работает для анимации представления вдоль пути, однако мне нужно, чтобы пользователь мог перетаскивать путь. –

+0

Пожалуйста, см. Мое редактирование..и думаю, я ответил вам. Надеюсь, это поможет –

+0

Я вижу, где вы собираетесь с этим - это имеет смысл, но я волнуюсь, что он существенно избавит вас от пользователя. Я также должен был указать, что движение должно быть двунаправленным, позволяя пользователю перемещаться вперед или назад вдоль пути в зависимости от того, где они перетаскиваются. Тем не менее, я буду играть с вашей идеей, чтобы проверить, могу ли я работать с надлежащей функциональностью перетаскивания. –