インターネットで解決策を探しています。私が見つけることができるものは何もありません。だから:私はUINavigationControllerを使用しています。 2つのUIViewControllersをプッシュします。 2番目にプッシュされたViewControllerでは、このコードを実行しています:
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error {
NSLog([error localizedDescription]);
[self.navigationController popViewControllerAnimated:YES]; }
予想されることは、最後にプッシュされたViewControllerが消えることです。このアプリでは、いくつかの場所でこれを行っていますが、この非常にViewControllerで期待されるすべての場所で正常に動作します。何が起こるかは、戻るボタンだけが画面から消える(アニメーション化される)が、他のすべては画面に残るということです。コンソール出力では、この行を実行すると2つのことが出力されます。
2011-03-14 16:32:44.580 TheAppXY [18518:207]ネストされたポップアニメーションにより、ナビゲーションバーが破損する可能性があります
2011-03-14 16:32:53.507 TheAppXY [18518:207]予期しない状態でナビゲーション遷移を終了します。ナビゲーションバーのサブビューツリーが破損する場合があります。
情報が見つからない2つのエラーメッセージ。 XCode 4とiOS SDK 4.3を使用しています。たぶん誰もがこの問題で私を助けることができます。
私は私のコードで同様の状況に遭遇し、メッセージは言った:
ネストされたプッシュアニメーションにより、ナビゲーションバーが破損する場合がある
予期しない状態でのナビゲーション遷移の仕上げ。ナビゲーションバーのサブビューツリーが破損する可能性があります。
この問題に対する私の発見は、2つのView Controllerをすばやく連続してプッシュし、両方がアニメーション化されたことです。
あなたの場合、複数のView Controllerをアニメーションで次々とポップしているようです。
したがって、あるビューがアニメーションを実行している間は、別のビューでアニメーションを開始しないでください。
また、1つのビューでアニメーションを無効にすると、エラーメッセージが消えることもわかりました。
私の場合、2つのView Controllerを次々にプッシュするつもりはなかったため、制御ロジックに問題がありました。 1つはスイッチケースロジック内にプッシュされ、もう1つは終了後にプッシュされていました。
これが誰かを助けることを願っています。
これは、viewDidAppear
の前にポップしようとするといつでも取得できます。フラグを設定した場合、viewDidAppear
でそのフラグをチェックするだけで、問題は発生しません。
UINavigationControllerのドロップイン置換を作成しました。これはアニメーションをキューに入れ、この問題を完全に回避します。
BufferedNavigationController から取得します
私もこの問題を抱えていましたが、これが私の原因でした:
私の修正? if ... thenステートメントを強化し、selectedSegmentIndex == -1のときにUISegmentedControl IBActionsのコードを実行することで保釈しました。
「プッシュ」エラーではなく「ポップ」アニメーションエラーが発生した理由はまだわかりませんが、少なくとも私のエラーを把握して修正しました。
これが他の人の助けになることを願っています!
ストーリーボードを使用すると、この問題が発生します。間違いを犯しました。SegueWithIdentifierを実行するアクションを持つUIButtonがあります。このため、プッシュセグエをボタンで他のViewControllerとリンクしているため、この問題が発生します。
解決するには:UIButtonでボタンアクションをリンクし、2つのViewController間でプッシュセグエをリンクします。
MilGraとAndrewの回答を組み合わせることで、確実に機能し、ドロップイン式のUINavigationControllerをより簡単に置き換えることができました。
これにより、MilGraの答えが改善され、プッシュとポップで動作するようになりましたが、AndrewのBufferedNavigationControllerよりも簡単です。 (BufferedNavigationControllerを使用すると、ときどき完了しないトランジションが発生し、黒い画面しか表示されませんでした。)
このすべてはiOS8では必要ないようですが、iOS7ではまだ必要でした。
@implementation UINavigationControllerWithQueue {
NSMutableArray *waitingList;
}
-(void) viewDidLoad {
[super viewDidLoad];
self.delegate = self; // NOTE: delegate must be self!
waitingList = [[NSMutableArray alloc] init];
}
# pragma mark - Overrides
-(void) pushViewController: (UIViewController*) controller
animated: (BOOL) animated {
[self queueTransition:^{ [super pushViewController:controller animated:animated]; }];
}
- (UIViewController *)popViewControllerAnimated:(BOOL)animated {
UIViewController *result = [self.viewControllers lastObject];
[self queueTransition:^{ [super popViewControllerAnimated:animated]; }];
return result;
}
- (NSArray*)popToRootViewControllerAnimated:(BOOL)animated {
NSArray* results = [self.viewControllers copy];
[self queueTransition:^{ [super popToRootViewControllerAnimated:animated]; }];
return results;
}
# pragma mark - UINavigationControllerDelegate
-(void) navigationController: (UINavigationController*) navigationController
didShowViewController: (UIViewController*) controller
animated: (BOOL) animated {
[self dequeTransition];
}
# pragma mark - Private Methods
-(void) queueTransition:(void (^)()) transition {
[waitingList addObject:transition];
if (waitingList.count == 1) {
transition();
}
}
-(void) dequeTransition {
if (waitingList.count > 0) {
[waitingList removeObjectAtIndex:0];
}
if (waitingList.count > 0) {
void (^transition)(void) = [waitingList objectAtIndex:0];
if (transition) {
transition();
}
}
}
@end
ええ、残念ながらAppleはUINavigationControllerのアニメーションを同期しませんでした。Andrewのソリューションは優れていますが、機能全体をカバーしたくない場合は、次の2つのメソッドをオーバーライドします。
// navigation end event
- ( void ) navigationController : ( UINavigationController* ) pNavigationController
didShowViewController : ( UIViewController* ) pController
animated : ( BOOL ) pAnimated
{
if ( [ waitingList count ] > 0 ) [ waitingList removeObjectAtIndex : 0 ];
if ( [ waitingList count ] > 0 ) [ super pushViewController : [ waitingList objectAtIndex : 0 ] animated : YES ];
}
- ( void ) pushViewController : ( UIViewController* ) pController
animated : ( BOOL ) pAnimated
{
[ waitingList addObject : pController ];
if ( [ waitingList count ] == 1 ) [ super pushViewController : [ waitingList objectAtIndex : 0 ] animated : YES ];
}
そして、waitingListというNSMutableArrayインスタンス変数を作成すれば完了です。