6

こんにちは、私は iPad アプリに取り組んでおり、アプリがバックグラウンドになったときにすべてのポップオーバー(存在する場合) を閉じる必要があります。

私はオンラインでいくつかの研究を行いましたが、それを行う簡単な方法が見つかりませんでした. ここで私のアイデアをいくつか共有し、それを行うためのより良い方法があるかどうかを確認したいと思います.

1, デリゲートの didEnterBakcground でポップオーバーを無視します。すべてのポップオーバー参照を追加する必要があるため、実用的ではないようです。

2、現在のウィンドウですべてのビューを再帰的に調べて、(class = _UIPopoverView) でポップオーバー ビューを見つけます。少しハックで危険なようです。

3、ポップオーバーを所有する各オブジェクトに UIApplicationDidEnterBackgroundNotificationgroundNotification を設定し、それらを閉じます。これは理にかなっているように見えますが、アプリに何百ものポップオーバーがある場合は本当に面倒です。

4, -(void)dismissWhenAppWillEnterBackground; というカテゴリ メソッドを追加してみてはどうでしょうか。通知を登録します。

それとももっと簡単にできる方法はありますか?

4

4 に答える 4

10

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
于 2013-08-02T23:11:41.073 に答える
3

カテゴリメソッド-(void)dismissWhenAppWillEnterBackgroundを UIPopoverController に追加し、 UIApplicationWillEnterBackgroundNotificationgroundNotificationを登録するという、より良い答えがあるかもしれません。

于 2013-07-29T23:50:21.567 に答える
2

いくつかのオプションのメソッドを使用してプロトコルを作成します。

- (void)appWillEnterBackground;
- (void)appWillBecomeActive;

ビュー コントローラーを実装してから、アプリ デリゲートでルート ビュー コントローラーにアクセスし、それらのメソッドに応答するかどうかを確認し、アプリがバックグラウンドになってアクティブになったときにそれらを呼び出します。ルート ビュー コントローラーは簡単に取得できるはずです。ビューコントローラーの階層がある場合は、呼び出しを転送する必要がある場合があります。

たとえば、ポップオーバー解除コードを に追加appWillEnterBackgroundします。

于 2013-07-29T08:21:39.140 に答える
2
  1. アプリケーション内のすべてのビュー コントローラーの uiviewcontroller 基本クラスを作成します。
  2. 特定のビューコントローラーのポップオーバー ビューへの参照を含む配列を追加します。
  3. 現在のviewcontroller iin app delegate への参照を維持します。
  4. アプリがバックグラウンドに入ると、現在のビューコントローラーを取得し、ポップオーバー配列をトラバースして、すべてのポップオーバーを閉じます。
于 2013-08-04T17:21:49.937 に答える