首先,建议检查是否正在显示弹出框,这也将方便地检查它是否已分配:
if ([self.popover isPopoverVisible]) {
[self.popover dismissPopoverAnimated:NO];
}
现在,问题是,如果像这样以编程方式关闭弹出框,则不会获得委托回调- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
,但是您需要对弹出框的强引用,直到它不再可见。
这样做的方法是延迟将属性设置为 nil,直到您返回主运行循环,因为当您返回主运行循环时,所有动画都将完成,因此弹出框将不再可见。
您需要将设置 popover 为 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,正如 Chris Loonam 的回答所提到的