web-dev-qa-db-ja.com

警告:既に表示されているMainTableViewControllerにModalTableViewControllerを表示しようとしています(null)

ポップオーバーに問題があります。セルをタップすると、ポップオーバーが読み込まれ、詳細が選択されます。すべて正常に動作しますが、セルをもう一度押すと、次のメッセージが表示されます。

警告:すでに表示されているMainTableViewController ...でModalTableViewController ...を表示しようとしています(null)

別のセルをタップしても、この警告は表示されません。同じ行をもう一度タップした場合のみ。

いろいろ試してみましたが、この問題を解決することはできません。私はこのようにポップオーバーをロードします:

var popover: UIPopoverController!
var popoverContent: ModalTableViewController!

そして私のセルタップで:

popoverContent = self.storyboard.instantiateViewControllerWithIdentifier("ModalTableViewController") as ModalTableViewController

popoverContent.selectedQuestionID = indexPath!.row               
popover = UIPopoverController(contentViewController: popoverContent)
popover.delegate = self

popover.presentPopoverFromRect(currentCell.LabelCellTitle.frame, inView: currentCell.LabelCellTitle.superview, permittedArrowDirections: UIPopoverArrowDirection.Left, animated: true)

そして却下する

func popoverControllerDidDismissPopover(popoverController: UIPopoverController!) {

    popover.dismissPopoverAnimated(false) // just to check

    self.popover = nil
    self.popoverContent = nil

}

何か案は?

編集:

で確認する場合:

if(self.popoverContent == nil) {

開く前に、同じセルをもう一度タップしてもゼロではないことがわかります。

もう一度編集:

少し異なる設定で作成すると、同じ問題が発生します。

カスタム1x1pxボタン。ポップオーバーとセグエを接続します。セルをタップすると、ボタンがセルに移動し、ポップオーバーが開きます。

そのため、ストーリーボードエディタでのみ、ポップオーバーを開くためのコードはありません。

同じポップオーバーをもう一度タップすると、同じエラーメッセージが(時々)表示されます。

49
derdida

まだSwiftではありませんが、Objective-Cの場合は、performSelector呼び出しでpresentViewController呼び出しをラップしました。

-(void) present
{
    [self performSelector: @selector(ShowModalTableViewController) withObject: nil afterDelay: 0];
}

-(void) ShowModalTableViewController
{
    [self presentViewController: ctrlModalTableViewController animated: true completion: nil];
}
55
Aace

この問題は、セグエ/プレゼンを内部から実行しようとしたために発生しました。

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex

私はそれを次のように変更しました:

- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex

そしてそれはそれを修正しました!

137
Steve

これも機能します:

dispatch_async(dispatch_get_main_queue(), ^ {
        [self presentViewController:vc animated:YES completion:nil];
});
52
Harris

これはポップオーバーで何かを提示するのに当てはまるようです。これまでのすべての応答が機能する理由は、ポップオーバー(またはアクティビティシートなど)が却下される前に実行されているアクションが発生するためです。

可能であれば、まずポップオーバーを閉じてから、モーダルを提示してください。

5
Jeff

このコードスニペットをメインのuiviewcontrollerのViewDidLoad()に簡単に追加するだけです

 definesPresentationContext = true
4
Naomi Osaka

これはiOS 8iPad8以下のiOSでは実際に発生しません。そこに条件を配置できます。

if ([controller respondsToSelector:@selector(popoverPresentationController)])
{
    // iOS8
    controller.popoverPresentationController.sourceView = self.view; // or any of your UIiew
}

ただし、このコードの変更については、スティーブのポイント( https://stackoverflow.com/a/26380194/36231 )も考慮してください。

4
Vaibhav Saran

これは、新しいView Controllerのプレゼンテーション呼び出しの時点でUIActionSheetが表示された場合に発生します。たとえば、このコードは私のために機能します

    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        [controller presentViewController:modalViewController animated:YES completion:NULL];
    }];
3
Tim

私にとっては、NavigationItemの一部として2つのUIBarButtonアイテムがあり、両方が独自のコントローラーを使用してポップオーバーとしてビューを開くトリガーされたセグエを持っているときに発生しました。 1つのポップオーバーは、他のBarButtonItemをタップしても自動的に消えません。ただし、ポップオーバー以外の場所でタップすると、却下されます。 UINavigationControllerをオーバーライドし、_presentViewController:animated:completion_の拡張バージョンを追加しました

_/*
 * Workaround for apparent bug in iPad that popover does not automatically dismiss if another bar button item is pressed
 */

- (void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion {

    /*
     * Make sure this runs in the main queue
     */
    dispatch_async(dispatch_get_main_queue(), ^ {
        if (
            [self.presentedViewController isKindOfClass:[ViewController1 class]]
            || [self.presentedViewController isKindOfClass:[ViewController2 class]]
            || [self.presentedViewController isKindOfClass:[ViewController3 class]]
            || [self.presentedViewController isKindOfClass:[ViewController4 class]]
            ) {
            [self dismissViewControllerAnimated:YES completion:^{
                [super presentViewController:viewControllerToPresent animated:flag completion:completion];
            }];
        }

        else {
            [super presentViewController:viewControllerToPresent animated:flag completion:completion];
        }
    });
}
_

dispatch_async(dispatch_get_main_queue(), ^ {})は本当に必要ではないと思います。念のため追加しました。

1
zero0cool

私の場合、誤ってボタンをIBActionStoryboard Segueに種類Present As Popoverで同時にリンクしてしまいました。これを修正するために行ったのは、ボタンのIBActionへのTouch Up Insideイベントリンクを削除し、Storyboard Segueのみを使用することでした。

0
Willy