UIPopoverController
これは、あなたが求めていることを行うドロップイン カテゴリです。
基本的に、カテゴリinitWithContentViewController:
はライブUIPopoverController
インスタンスを追跡できるようにスウィズルしますNSHashTable
(それ自体は、含まれている UIPopoverControllers への弱い参照を保持するため、それらを生きたまま保持しません) UIApplicationDidEnterBackgroundNotification
。表示されているものはすべて却下します。
これを拡張して、Apple の「一度に 2 つのポップオーバーを表示しない」というルールを実装するとよいでしょう。
私は実稼働アプリでのメソッド スウィズリングの大ファンではありませんが、これはかなり安全に思えます。
使用上の特別な指示はありません。プロジェクトにカテゴリを含めて、通常どおり 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