まず、ポップオーバーが表示されているかどうかを確認することをお勧めします。これにより、ポップオーバーが割り当てられているかどうかも簡単に確認できます。
if ([self.popover isPopoverVisible]) {
[self.popover dismissPopoverAnimated:NO];
}
さて、問題は、このようにプログラムでポップオーバーを閉じると、デリゲート コールバックを取得できないことですが- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
、ポップオーバーが表示されなくなるまで、ポップオーバーへの強い参照が必要です。
これを行う方法は、メインの実行ループに戻るまでプロパティを nil に設定するのを遅らせることです。メインの実行ループに戻ると、すべてのアニメーションが終了し、ポップオーバーが表示されなくなります。
ポップオーバーを nil に設定するコードを別のメソッドに移動する必要があります。
- (void)releasePopover {
self.popover.delegate = nil;
self.popover = nil;
}
次に、ローテーション コールバックで、このメソッドを追加してメインの実行ループで起動します。私は呼び出し操作をメインの実行ループに追加することでこれを行うのが好きです。
if ([self.popover isPopoverVisible]){
[self.popover dismissPopoverAnimated:NO];
NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(releasePopover) object:nil];
[[NSOperationQueue mainQueue] addOperation:invocationOperation];
}
最後に、きれいにするために、おそらくコールバック-releasePopover
内から呼び出すことをお勧めし- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
ます。
したがって、すべてをまとめると、次のようになります。
- (void)releasePopover
{
self.popover.delegate = nil;
self.popover = nil;
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if ([self.popover isPopoverVisible]){
[self.popover dismissPopoverAnimated:NO];
NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(releasePopover) object:nil];
[[NSOperationQueue mainQueue] addOperation:invocationOperation];
}
}
- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
{
[self releasePopover];
}
そうは言っても、正当な理由がない限り、ポップオーバーを再利用するために維持し、メモリ不足の警告が表示された場合やビューがアンロードされた場合にのみ nil に設定することをお勧めします。