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

Ios 当iPad应用程序进入后台时关闭popover,ios,ipad,uipopovercontroller,popover,Ios,Ipad,Uipopovercontroller,Popover,您好,我正在开发一款iPad应用程序,当应用程序进入后台时,我需要关闭所有弹出窗口(如果有) 我在网上做了一些研究,但没有找到简单的方法。我想在这里分享我的一些想法,看看是否有更好的方法 1、在代理中取消didEnterBakcground中的弹出框。似乎不实用,因为我们必须在引用中添加所有popover 2、在当前窗口中递归地浏览所有视图,以查找popover视图的依据(class=\u UIPopoverView)。这似乎有点骇客和危险 3、在拥有Popover的每个对象中设置应用程序标识B

您好,我正在开发一款iPad应用程序,当应用程序进入后台时,我需要关闭所有弹出窗口(如果有)

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

1、在代理中取消didEnterBakcground中的弹出框。似乎不实用,因为我们必须在引用中添加所有popover

2、在当前窗口中递归地浏览所有视图,以查找popover视图的依据(class=\u UIPopoverView)。这似乎有点骇客和危险

3、在拥有Popover的每个对象中设置应用程序标识BackgroundNotificationGroundNotification,并将其关闭。这似乎是合理的,但如果你的应用程序中有数百个弹出窗口,那就真的很麻烦了

4、如何添加一个分类方法,比如-(void)dismissweappwillenterbackground;和注册通知


或者有更简单的方法吗?

使用两种可选方法编写协议:

- (void)appWillEnterBackground;
- (void)appWillBecomeActive;
让你的视图控制器实现它,然后在你的应用程序委托中,访问你的根视图控制器,检查它是否响应这些方法,并在应用程序进入后台并激活时调用它们。 您应该能够轻松获得根视图控制器。如果有视图控制器的层次结构,则可能需要转发调用


例如,在
appWillEnterBackground
中添加您的popover解雇代码。

我可能有一个更好的答案,那就是添加一个类别方法-(void)解除WillEnterBackground到UIPopoverController并注册UIApplicationWillEnterBackgroundNotificationgroundNotification。

以下是
UIPopoverController
上的一个下拉列表,它满足了您的要求

基本上,该类别将
initWithContentViewController:
切换,以便它可以跟踪
NSHashTable
中的实时
UIPopoverController
实例(它本身不会使包含的UIPopoverController保持活动状态,因为它保持对它们的弱引用)它还监视
UIApplicationIdentinterBackgroundNotification
,当该通知到达时,它会迭代实时UIPopOvercontroller的集合,并取消显示的任何内容

将其扩展以实现苹果的“决不允许两个弹出窗口同时显示”规则可能会很好

我不太喜欢在生产应用程序中使用这种方法,但这似乎很安全

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

#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
#导入
@超控器接口(自动关闭)
@结束
@超控器的实现(自动解除)
静态NSHashTable*ts_爆竹台;
+(空)荷载
{
SEL originalSelector=@选择器(initWithContentViewController:);
SEL replacementSelector=@selector(ts_initWithContentViewController:);
方法originalMethod=class_getInstanceMethod([UIPopoverController class],originalSelector);
方法replacementMethod=class_getInstanceMethod([UIPopoverController class],replacementSelector);
方法交换实施(原始方法、替代方法);
[[NSNotificationCenter defaultCenter]添加观察者:self
选择器:@selector(ApplicationIdentinterBackgroundNotification:)
名称:UIApplicationIdentinterBackgroundNotification
对象:无];
}
-(id)ts_initWithContentViewController:(UIViewController*)contentViewController
{
UIPopoverController*pc=[self ts_initWithContentViewController:contentViewController];
静态调度一次;
一次发送(一次发送)^{
ts_popushtable=[NSHashTable weakobjectshtable];
});
[ts_PopOvershashTable addObject:pc];
返回pc;
}
+(无效)应用程序标识符背景通知:(NSNotification*)n
{
用于(UIPopoverController*ts_PopOvershashTable中的pc)
{
如果(pc.isPopoverVisible)
{
[个人电脑解雇:否];
}
}
}
@结束
  • 为应用程序中的所有视图控制器创建uiviewcontroller基类
  • 添加一个数组,其中包含对特定viewcontroller中的popover视图的引用
  • 维护对当前viewcontroller iin应用程序委托的引用
  • 当应用程序进入后台时,获取当前的viewcontroller并遍历popover数组并关闭所有popover

  • 为什么你的应用程序中会有数百个弹出窗口?只需将活动的弹出窗口设置为观察UIApplicationIdentinterBackgroundNotificationGroundNotification或WillEnterBackgroundNotification,然后让它们自行退出即可。@Jessedc It部门需要这些弹出窗口。我只是想看看是否有比这更好的解决办法。谢谢