当iPad应用程序进入后台时,关闭popover

Thi*_*ris 6 popover ipad uipopovercontroller ios

嗨,我正在开发一个iPad应用程序,并且要求在应用程序进入后台时关闭所有弹出窗口(如果有的话).

我在网上做了一些研究,并没有找到一个简单的方法来做到这一点.我想在这里分享一些我的想法,看看是否有更好的方法来做到这一点.

1,在委托中取消 didEnterBakcground中的popovers.似乎不实用,因为我们必须添加所有popovers引用.

2,在当前窗口中递归遍历所有视图,以通过(class = _UIPopoverView)查找弹出视图.这看起来有点hacky和危险.

3,拥有弹出窗口的每个对象中设置UIApplicationDidEnterBackgroundNotificationgroundNotification并将其关闭.这似乎是合理的,但如果你的应用程序中有数百个弹出窗口,那真的很麻烦.

4,如何添加类别方法说 - (void)dismissWhenAppWillEnterBackground; 并注册通知.

或者有更容易的方法吗?

Tom*_*ift 10

这是一个简单的类别UIPopoverController就是你所要求的.

基本上这个类别可以调整,initWithContentViewController:以便它可以跟踪一个实时UIPopoverController实例NSHashTable(它本身并不包含所包含的UIPopoverControllers,因为它保留了对它们的弱引用.)它还监视它UIApplicationDidEnterBackgroundNotification,当它到达时它会迭代实时UIPopoverControllers和驳回任何正在展示的东西.

可能很高兴将其扩展到实现Apple所拥有的"永不允许两个popovers立即显示"规则.

我不是生产应用程序中混乱方法的忠实粉丝,但这看起来非常安全.

没有特别的使用说明.只需在项目中包含该类别,即可正常使用UIPopoverControllers.

#import <objc/runtime.h>

@interface UIPopoverController (autodismiss)
@end

@implementation UIPopoverController (autodismiss)

static NSHashTable* ts_popoverHashTable;

+ (void) load
{
    SEL originalSelector = @selector(initWithContentViewController:);
    SEL replacementSelector = @selector(ts_initWithContentViewController:);
    Method originalMethod = class_getInstanceMethod( [UIPopoverController class], originalSelector);
    Method replacementMethod = class_getInstanceMethod( [UIPopoverController class], replacementSelector);
    method_exchangeImplementations(originalMethod, replacementMethod);

    [[NSNotificationCenter defaultCenter] addObserver: self
                                             selector: @selector( applicationDidEnterBackgroundNotification: )
                                                 name: UIApplicationDidEnterBackgroundNotification
                                               object: nil];
}

- (id) ts_initWithContentViewController: (UIViewController*) contentViewController
{
    UIPopoverController* pc = [self ts_initWithContentViewController: contentViewController];

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{

        ts_popoverHashTable = [NSHashTable weakObjectsHashTable];
    });

    [ts_popoverHashTable addObject: pc];

    return pc;
}

+ (void) applicationDidEnterBackgroundNotification: (NSNotification*) n
{
    for ( UIPopoverController* pc in ts_popoverHashTable )
    {
        if ( pc.isPopoverVisible )
        {
            [pc dismissPopoverAnimated: NO];
        }
    }
}

@end
Run Code Online (Sandbox Code Playgroud)