首先,建议检查浮层是否正在显示,这也会方便地检查它是否已分配:
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,正如Chris Loonam的答案所提到的那样。