web-dev-qa-db-ja.com

<UINavigationController:0xa98e050>の外観遷移を開始/終了するための不均衡な呼び出し

私が得たコードをコンパイルしている間

<UINavigationController: 0xa98e050>の外観遷移を開始/終了するための不均衡な呼び出し」

警告。

これが私のコードです

KVPasscodeViewController *passcodeController = [[KVPasscodeViewController alloc] init];
passcodeController.delegate = self;

UINavigationController *passcodeNavigationController = [[UINavigationController alloc] initWithRootViewController:passcodeController];
[(UIViewController *)self.delegate presentModalViewController:passcodeNavigationController animated:YES];
20
KsK

私はこれが古い質問であることを知っていますが、これに再び遭遇した人のために、ここに私が見つけたものがあります。

第一に、質問は新しいviewControllerがどこで呼び出されたかを述べていません。
これは-(void)viewDidLoadから呼び出されたと思われます

適切なコードを-(void)viewDidAppear:に移動すると、問題は解消されます。

これは、-viewDidLoad、ビューは読み込まれましたが、まだ表示されておらず、アニメーションとビューは完了していません。

ウィンドウをプッシュすることが目的である場合は、ウィンドウが表示されてペイントされた後で実行します。

タイマーを使用してシステムの動作を制御していることに気付いた場合は、何が悪いのか、またはどのようにしてそれをより適切に実行できるのかを自問してください。

57
Mark Travis

この問題は、前のトランザクション(animation)の進行中に新しいView Controllerをプッシュしようとすると発生することがわかりました。

とにかく、私はそれがpresentModalViewController問題だと思います、セットanimated:NO問題を解決できる可能性があります

[(UIViewController *)self.delegate presentModalViewController:passcodeNavigationController animated:NO];

その他のオプションは:

NSTimerを取り、上記のコード間の呼び出しは.50 to 1秒かもしれません。これも役立つトリックです。したがって、以前のviewControllerはアニメーションを実行しました。

17
iPatel

この警告は、以前に含まれていたものをアニメーション化する前に新しいviewControllerをロードしようとすると表示されます。あなたの意図がそうすることであるならば、単にあなたのコードをdispatch_async(dispatch_get_main_queue()ブロックに追加してください:

dispatch_async(dispatch_get_main_queue(), ^(void){
        [(UIViewController *)self.delegate presentModalViewController:passcodeNavigationController animated:YES];
});

警告は消えます。

現代の解決策はこれかもしれません:

double delayInSeconds = 0.5;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds *   NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    [self.window.rootViewController presentViewController:yourVC animated:YES completion:nil];
});
3
Harald

あなたは多くのコンテキストを提供しなかったので、パスコードビューコントローラーを提示しているので、起動時にこのエラーが発生していると思います。

この警告を回避するために、アプリのデリゲートをナビゲーションルートビューコントローラーのデリゲートとして登録します。

- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    ((UINavigationController *)self.window.rootViewController).delegate = self;
    return YES;
}

次に、モーダルビューコントローラーをnavigationController:didShowViewController:animated: とともに dispatch_once

- (void) navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    static dispatch_once_t once;
    dispatch_once(&once, ^{
        KVPasscodeViewController *passcodeController = [[KVPasscodeViewController alloc] init];
        passcodeController.delegate = self;

        UINavigationController *passcodeNavigationController = [[UINavigationController alloc] initWithRootViewController:passcodeController];
        [(UIViewController *)self.delegate presentViewController:passcodeNavigationController animated:YES completion:nil];
    });
}

navigationController:didShowViewController:animated:は、ルートビューコントローラーが表示された後に呼び出され、外観の遷移を開始/終了するためのアンバランスな呼び出し警告が表示されなくなります。

1
0xced