2

解決しました。ばかげて恥ずかしい。インスタンス変数を使用していませんでした。実装で中括弧の外で宣言しました。

本当に苦労しています。アニメーションのカウントダウン タイマーを管理するビュー コントローラーがあります。アニメーションは、再帰的な UIView アニメーションと、減少する単純な int ivar を使用しています。次のようなものです (これは簡略化されたスニペットです)。

- (void) animate {
  [UIView animateWithDuration:0.75f
                        delay:0.25f
                      options:UIViewAnimationCurveEaseInOut
                   animations:^{ aView.center = newCenter;
                               counter--; } 
                   completion:^(BOOL finished) {
                            if (counter != 0) [self animate]; }];
}

カウントダウン中、ユーザーはタイマーがカウントダウンを終了するのを待つのではなく、スワイプして次のステップに進むことができます。ユーザーが新しいビュー コントローラー (現在のビュー コントローラーの新しいインスタンス) をスワイプすると、次のステップの値と共にスタックにプッシュされます。

TimerViewController * vc = (TimerViewController*)[self.storyboard instantiateViewControllerWithIdentifier:@"Timer"];
[vc setTask: _task + 1];
[self.navigationController pushViewController:vc animated:YES];

新しいView Controllerが所定の位置にスライドしてカウントダウンを開始しますが、以前のView Controllerはアニメーションを続けています。デバッガーでは、このView Controllerの別のインスタンスをはっきりと見ることができます。 aView が不規則に動く原因となるアニメーション。2 つの異なるビュー コントローラー インスタンスが同じ aView インスタンスをアニメーション化していますか?

スタック内の前のView Controllerからアニメーションを停止するにはどうすればよいですか? 私は入り込んでいますcounter = 0viewWillDisappear、他のあらゆる種類の絶望的なことは役に立ちません。ここで実際に動いているものを見逃しています。

どんな助けにも本当に感謝します。

更新 1viewWillDisappear (実装の追加):

-(void) viewWillDisappear:(BOOL)animated {
   [super viewWillDisappear:animated];
   counter = 0;
}

UPDATE 2 (インスタンスを表示するように編集)

独自の aView インスタンスを持つ複数の TimerViewController インスタンスがあることは明らかです。ブロック中にログを追加してanimations、現在のインスタンス、タスク、およびカウンターの値を表示しました。

2012-11-03 10:28:19.930 develop.[4362:907] [0x1f5a38f0]NiceTimer:viewWillAppear
2012-11-03 10:28:19.940 develop.[4362:907] [0x1f5a38f0](0)>03:00
2012-11-03 10:28:21.149 develop.[4362:907] [0x1f5a38f0](0)>02:59
2012-11-03 10:28:22.161 develop.[4362:907] [0x1f5a38f0](0)>02:58
2012-11-03 10:28:23.170 develop.[4362:907] [0x1f5a38f0](0)>02:57
2012-11-03 10:28:24.183 develop.[4362:907] [0x1f5a38f0](0)>02:56
2012-11-03 10:28:25.210 develop.[4362:907] [0x1f5a38f0](0)>02:55
2012-11-03 10:28:26.221 develop.[4362:907] [0x1f5a38f0](0)>02:54
2012-11-03 10:28:26.694 develop.[4362:907] ---swipe---
2012-11-03 10:28:26.698 develop.[4362:907] delegate:niceTimerViewControllerDidSwipe:duringTask
2012-11-03 10:28:26.713 develop.[4362:907] [0x1f5a38f0]NiceTimer:viewWillDisappear
2012-11-03 10:28:26.715 develop.[4362:907] [0x1f5b0ac0]NiceTimer:viewWillAppear
2012-11-03 10:28:26.720 develop.[4362:907] [0x1f5b0ac0](1)>02:00
2012-11-03 10:28:27.096 develop.[4362:907] [0x1f5a38f0]NiceTimer:viewDidDisappear
2012-11-03 10:28:27.099 develop.[4362:907] [0x1f5a38f0](0)>01:59
2012-11-03 10:28:27.748 develop.[4362:907] [0x1f5b0ac0](1)>01:58
2012-11-03 10:28:27.754 develop.[4362:907] [0x1f5a38f0](0)>01:57
2012-11-03 10:28:28.754 develop.[4362:907] [0x1f5b0ac0](1)>01:56
2012-11-03 10:28:28.763 develop.[4362:907] [0x1f5a38f0](0)>01:55
2012-11-03 10:28:29.764 develop.[4362:907] [0x1f5b0ac0](1)>01:54
2012-11-03 10:28:29.770 develop.[4362:907] [0x1f5a38f0](0)>01:53
2012-11-03 10:28:30.542 develop.[4362:907] ---swipe---
2012-11-03 10:28:30.545 develop.[4362:907] delegate:niceTimerViewControllerDidSwipe:duringTask:1
2012-11-03 10:28:30.560 develop.[4362:907] [0x1f5b0ac0]NiceTimer:viewWillDisappear
2012-11-03 10:28:30.562 develop.[4362:907] [0x1f5ac3d0]NiceTimer:viewWillAppear
2012-11-03 10:28:30.567 develop.[4362:907] [0x1f5ac3d0](2)>05:00
2012-11-03 10:28:30.593 develop.[4362:907] [0x1f5a38f0](0)>04:59
2012-11-03 10:28:30.601 develop.[4362:907] [0x1f5a38f0](0)>04:58
2012-11-03 10:28:30.617 develop.[4362:907] [0x1f5a38f0](0)>04:57
2012-11-03 10:28:30.620 develop.[4362:907] [0x1f5a38f0](0)>04:56

長々と申し訳ありませんが、これは実際に何が起こっているかを示しています。スワイプの後、プッシュがあります (コードは投稿の上部にあります)。タスクがインクリメント(0)>(1)>に進み、次のスワイプまで一定のままになると思います。代わりに、現在のカウンターの値を使用して、スタック上の以前の各インスタンスが起動し続けていることがわかります。前の各インスタンスのアニメーションは、現在のカウンターに対して続行されます

更新 3

スワイプ ハンドラーで呼び出されるデリゲートを実装しました。TVC1 は、プッシュされたときに TVC2 に渡されるデリゲートです。デリゲートは、removeAllAnimations などと呼ばれるカウンターを 0 に設定しますが、効果はありません。これならいけると本気で思いました。この時点で、その方法で解決しようとして間違った道を進んでいると思います。それがアプリ内の何か他のものではないことを確認するために、新しいプロジェクト、簡単な実装を作成しました。

-(void)timerViewControllerDidSwipe:(TimerViewController *)controller duringTask:(int)task {

    NSLog(@"timerViewControllerDidSwipe:duringTask:%d", task);
    counter = 0;
    [self.aView.layer removeAllAnimations];
    [self.view.layer removeAllAnimations];
    aView = nil;

    // This is showing everything I tried
}

更新 4

問題が見つかりました!すべてのインスタンスは同じ int を参照します。これがどのように可能かわかりません.intはクラスのインスタンスに固有のものではありません??

2012-11-03 13:16:49.336 develop.[4656:907] [animate:0x1ed8c790](1)>02:46
2012-11-03 13:16:49.340 develop.[4656:907] **[^anim:0x1ed8c790](1)>166(duration=0x6a748)**
2012-11-03 13:16:49.344 develop.[4656:907] [^after:0x1eddb8c0](0)>166
2012-11-03 13:16:49.352 develop.[4656:907] [animate:0x1eddb8c0](0)>02:45
2012-11-03 13:16:49.356 develop.[4656:907] **[^anim:0x1eddb8c0](0)>165(duration=0x6a748)**
4

2 に答える 2

1

TimerViewControllerをナビゲーションスタックにプッシュする前に、実行中のすべてのアニメーションを削除してみてください。

[aView.layer removeAllAnimations]; 
TimerViewController * vc = (TimerViewController*)[self.storyboard instantiateViewControllerWithIdentifier:@"Timer"];
[vc setTask: _task + 1];
[self.navigationController pushViewController:vc animated:YES];

また、インポートしたことを確認してください。インポートし<QuartzCore/QuartzCore.h>ないと、次のエラーが発生します。Receiver type 'CALayer' for instance message is a forward declaration

于 2012-11-02T21:03:01.720 に答える
0

修理済み。これ以上恥ずかしいことはありません。基本的な構文の問題。変数宣言を中括弧で囲みませんでした。これは私がしました:

@implementation TimerViewController 

int counter;

- (void) aMethod { }

@end

これの代わりに:

@implementation TimerViewController {

int counter;

}

- (void) aMethod { }

@end

私のエラーが誰かを助けることを願っています! それは私には決して起こらなかったでしょう。もう二度としない間違い。

于 2012-11-03T23:16:37.467 に答える