2013-07-05 40 views
6

您好我正在研究一個iPad應用程序,並要求關閉所有彈出窗口(如果有的話),當應用程序進入後臺。當iPad應用程序在後臺關閉popover

我在網上做了一些研究,並沒有找到一個簡單的方法來做到這一點。我想在這裏分享一下我的想法,看看是否有更好的方法來做到這一點。

1,關閉中的彈出式窗口代理中的didEnterBakcground。因爲我們必須在添加所有popovers參考,似乎並不現實。

2,通過所有視圖遞歸去在當前窗口中(類= _UIPopoverView)找到酥料餅的視圖。這似乎有點冒失和危險。

3,設置UIApplicationDidEnterBackgroundNotificationground通知每個對象誰擁有popovers和dismiss他們。這看起來很合理,但是如果您的應用中有數百個彈出窗口,那真的很麻煩。

4,如何添加類別方法說 - (void)dismissWhenAppWillEnterBackground;並註冊通知。

還是有更簡單的方法來做到這一點?

+2

爲什麼你會在你的應用程序中有數百個彈出菜單?只需設置活動彈出窗口即可觀察UIApplicationDidEnterBackgroundNotificationgroundNotification或willEnterBackground等效項,並讓他們自行解散。 – Jessedc

+0

@Jessedc這是業務需要有這些popovers。我只想看看是否有比這更好的解決方案。謝謝。 – ThinkChris

回答

9

這是UIPopoverController上的一個嵌入類別,它可以滿足您的要求。

基本上類別碎冰雞尾酒initWithContentViewController:,以便它可以在一個NSHashTable跟蹤現場UIPopoverController情況下(這本身並不持有包含UIPopoverControllers活着,因爲它保持弱引用他們。)它也監視UIApplicationDidEnterBackgroundNotification,當該到達它迭代實時UIPopoverControllers的集合並關閉所有正在顯示的集合。

這可能是很好的延長這個實現「永遠不允許兩個彈出顯示一次」規則,蘋果有。

我並不是在生產應用程序中使用swizzling方法的狂熱粉絲,但這看起來很安全。

沒有特別的使用說明。只需在您的項目中包含類別並正常使用您的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 
2

寫一對夫婦的可選方法的協議:

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

讓您的視圖控制器來實現它,然後在您的應用程序委託,訪問你的根視圖控制器,檢查其是否迴應這些方法和調用他們在應用程序要後臺並變得活躍時。 您應該能夠輕鬆獲得根視圖控制器。如果您有視圖控制器的層次結構,則可能需要轉發呼叫。例如

例如,在appWillEnterBackground中添加您的popover解僱代碼。

3

我可以有一個更好的答案,這是添加類方法- (無效)dismissWhenAppWillEnterBackground到UIPopoverController和註冊UIApplicationWillEnterBackgroundNotificationgroundNotification

2
  1. 用於在該應用程序的所有視圖控制器創建一個UIViewController基類。
  2. 添加一個數組,其中包含對特定視圖控制器中彈出窗口視圖的引用
  3. 在應用程序委託中維護對當前viewcontroller的引用。
  4. 當應用程序進入後臺時,獲取當前viewcontroller並遍歷popover數組並關閉所有彈出窗口。
相關問題