1

私が目指しているパターンは、車のギアシフターのパターンです。これは、90度の角度で約9本の直線で構成されており、ユーザーがUIViewをドラッグする必要があります。

私の最初のアプローチは、ビューの中心の座標を確認し、特定の条件を満たす場合は、x/yを適切に有効/無効にすることでした。これにより、維持するのが面倒になる長い複雑なifステートメントが作成されました。ほとんどの場合、機能します。ときどきスタックしますが、修正するために何をする必要があるかはわかっています。

2番目のアイデアは、移動したいビューに固定する正方形を許可するのに十分な幅のスペースを中央に配置して、パスの周りに非常に単純な長方形のコレクションを作成することです。そうすれば、衝突検出を使用して、パスに沿ってビューを維持できるようになります。これは、非常に基本的なブロックパスでは機能するように見えますが、より複雑なパスでは実行できません。

私の望む効果を達成する他の方法はありますか?

ところで、これが最初のシナリオの私の非常にラフで非効率的なテストです:

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

2 に答える 2

2

ええ、あなたはそれらの多くなしでアニメーションを行うことができます..elses、あなたはbrezierパスに沿ってnanimationを描くためにコアアニメーションの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を作成します。

于 2012-05-17T11:46:04.073 に答える
0

問題を完全に解決する解決策を見つけることができなかったため、条件とポイントを使用する必要がありました。誰かがより良い解決策を持っているなら、私は将来それを正しいとマークすることを嬉しく思います。

于 2012-05-30T02:11:30.400 に答える