ポップオーバーに問題があります。セルをタップすると、ポップオーバーが読み込まれ、詳細が選択されます。すべて正常に動作しますが、セルをもう一度押すと、次のメッセージが表示されます。
警告:すでに表示されている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ボタン。ポップオーバーとセグエを接続します。セルをタップすると、ボタンがセルに移動し、ポップオーバーが開きます。
そのため、ストーリーボードエディタでのみ、ポップオーバーを開くためのコードはありません。
同じポップオーバーをもう一度タップすると、同じエラーメッセージが(時々)表示されます。
まだSwiftではありませんが、Objective-Cの場合は、performSelector呼び出しでpresentViewController呼び出しをラップしました。
-(void) present
{
[self performSelector: @selector(ShowModalTableViewController) withObject: nil afterDelay: 0];
}
-(void) ShowModalTableViewController
{
[self presentViewController: ctrlModalTableViewController animated: true completion: nil];
}
この問題は、セグエ/プレゼンを内部から実行しようとしたために発生しました。
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
私はそれを次のように変更しました:
- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
そしてそれはそれを修正しました!
これも機能します:
dispatch_async(dispatch_get_main_queue(), ^ {
[self presentViewController:vc animated:YES completion:nil];
});
これはポップオーバーで何かを提示するのに当てはまるようです。これまでのすべての応答が機能する理由は、ポップオーバー(またはアクティビティシートなど)が却下される前に実行されているアクションが発生するためです。
可能であれば、まずポップオーバーを閉じてから、モーダルを提示してください。
このコードスニペットをメインのuiviewcontrollerのViewDidLoad()
に簡単に追加するだけです
definesPresentationContext = true
これはiOS 8のiPad8以下のiOSでは実際に発生しません。そこに条件を配置できます。
if ([controller respondsToSelector:@selector(popoverPresentationController)])
{
// iOS8
controller.popoverPresentationController.sourceView = self.view; // or any of your UIiew
}
ただし、このコードの変更については、スティーブのポイント( https://stackoverflow.com/a/26380194/36231 )も考慮してください。
これは、新しいView Controllerのプレゼンテーション呼び出しの時点でUIActionSheetが表示された場合に発生します。たとえば、このコードは私のために機能します
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[controller presentViewController:modalViewController animated:YES completion:NULL];
}];
私にとっては、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(), ^ {})
は本当に必要ではないと思います。念のため追加しました。
私の場合、誤ってボタンをIBAction
とStoryboard Segue
に種類Present As Popover
で同時にリンクしてしまいました。これを修正するために行ったのは、ボタンのIBAction
へのTouch Up Inside
イベントリンクを削除し、Storyboard Segue
のみを使用することでした。