3

だから、今私はiphone5画面の下部を横切って左右に跳ねるロケットを持っています。ただし、ロケットの左右への移動を停止し、ユーザーが画面に触れると上に移動するようにします(したがって、画面に触れるとロケットが離陸します)。

まず、viewDidAppearで、2秒後にspawnRocketメソッドを実行するようにコンパイラーに指示しました。

このspawnRocket方法では、ロケットの画像とフレームを作成し、それをビューに追加して、ロケットを画面の右側に送信するuiviewアニメーションを実行しました。uiviewアニメーションメソッドのfinishedパラメーターで、moveRocketLeftメソッドを実行するようにコンパイラーに指示しました。

moveRocketLeftメソッドでは、ロケットを画面の左側に送信するアニメーションを実行し、finishedパラメーターでは、moveRocketRightメソッドを実行しました。

moveRocketMethodは基本的にspawnRocketメソッドですが、ロケットの画像とフレームを確立してビューに追加しない点が異なります。

それで、このすべての後、私は-touchesBegan:withEvent:メソッドを実装しようとしました。ロケットyを画面から上に向けて変更し、xをユーザーが画面に触れたときの現在のxに変更するuiviewアニメーションを実行してみました。

ただし、ロケットフレームを呼び出しても、アニメーション中にロケットがどのように見えるかは返されません。実際には、アニメーション化が完了したときにロケットフレームがどのようになるかを返すだけです。だから、私が欲しいフレームを取得するには、私は呼び出す必要がありますlayerか?そのレイヤーがアニメーション中にuiimageviewの実際の場所を返す場所を読んだことを覚えています。ただし、レイヤーにはプロパティ境界のみがあり、フレームはないため、少し混乱しています。

また、新しいアニメーションを呼び出し[self.view.layer removeAllAnimations];て実行しようとしましたが、これは厄介なものになりますが、このremoveAllAnimations方法は機能しませんでした(とにかく、遅れていると聞いたので、それを使用するというアイデアはあまり好きではありません)。

touchesBegan:withEvent:だから誰もがロケットが正しく離陸できるようにメソッドを実装する方法を知っていますか?(または、プログラム全体を変更する必要があると思われる場合は、お気軽にご協力ください)

    #import "ViewController.h"
    #import <QuartzCore/QuartzCore.h>
    @interface ViewController ()
    @property UIImageView *rocket;
    @end

    @implementation ViewController


    @synthesize rocket=_rocket;

    - (void)viewDidLoad
    {
        [super viewDidLoad];

    }

    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[self.view.layer removeAllAnimations];
     //   [UIView animateWithDuration:3 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^(){self.rocket.frame=CGRectMake(self.rocket.frame.origin.x, -40, 25, 40);} completion:^(BOOL finished){}];

    // this didn't work :(
    }



    -(void)viewDidAppear:(BOOL)animated{
        [self performSelector:@selector(spawnRocket) withObject:self afterDelay:2];
    }
    -(void)spawnRocket{
        self.rocket=[[UIImageView alloc]initWithImage:[UIImage imageNamed:@"default.png"]]; //places imageview right off screen
        self.rocket.frame=CGRectMake(-25, 420, 25, 40);

        [self.view addSubview:self.rocket];
        [UIView animateWithDuration:1.5 delay:0 options:UIViewAnimationOptionCurveLinear animations:^(){self.rocket.frame=CGRectMake(295, 420, 25, 40);}  completion:^(BOOL finished){if (finished)[self moveRocketLeft]; }];


    }

    -(void) moveRocketLeft{
        [UIView animateWithDuration:1.5 delay:0 options:UIViewAnimationOptionCurveLinear animations:^(){self.rocket.frame=CGRectMake(0, 420, 25, 40);} completion:^(BOOL finished){if (finished)[self moveRocketRight];}];
    }

        -(void)moveRocketRight{
          [UIView animateWithDuration:1.5 delay:0 options:UIViewAnimationOptionCurveLinear animations:^(){self.rocket.frame=CGRectMake(295, 420, 25, 40);} completion:^(BOOL finished){if (finished)[self moveRocketLeft];}];
        }
    - (void)didReceiveMemoryWarning
    {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }

    @end
4

1 に答える 1

1

これはトリックを行う必要があります

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    CALayer *rocketPresentationLayer = [self.rocket.layer presentationLayer];
    self.rocket.layer.position = rocketPresentationLayer.position;
    [UIView animateWithDuration:3 delay:0 options:UIViewAnimationOptionCurveEaseIn|UIViewAnimationOptionBeginFromCurrentState animations:^(){self.rocket.frame=CGRectMake(self.rocket.frame.origin.x, -40, 25, 40);} completion:^(BOOL finished){}];
}

注1:ロケットが垂直離陸しているときに、ユーザーがロケットをもう一度タップしたかどうかを確認するためのロジックをここに入れませんでした。BOOLユーザーがロケットを打ち上げることに成功したかどうかを確認するために、または何かを追加することをお勧めします。そうであれば、垂直方向のアニメーションを再度実行しないでください。

注2:将来、ロケットが打たれたときにのみこれを発生させたい場合は、hitTestチェックを使用して条件付きでアニメーションを呼び出すことができます。

// Get the touch
UITouch *touch = [touches anyObject];
CGPoint touchPoint = [touch locationInView:self.view];

// See if we hit the rocket
CALayer *rocketPresentationLayer = [self.rocket.layer presentationLayer];
CALayer* hitTest = [rocketPresentationLayer hitTest:touchPoint];

// If we did, then stop animation and move upwards
if (hitTest) {
    ....
}

PS:また、ちょっとした言及として、@property UIImageView *rocket;に変更する必要があります@property (nonatomic) UIImageView *rocket;。これは主にパフォーマンス上の理由によるものです。ロケットが複数のスレッドからアクセスされることはないと思います(そうすべきではありません。UIです!)。

于 2012-11-03T21:51:32.480 に答える