web-dev-qa-db-ja.com

applicationDidBecomeActiveが呼び出されたときにアクティブなViewControllerに通知するにはどうすればよいですか?

私はここでトリックを逃しているように感じます...

ApplicationDidBecomeActiveが呼び出されたときに、現在アクティブなView ControllerでviewDidLoadまたはviewDidAppearを呼び出したいだけなので、アプリをバックグラウンドから再起動したときに、アニメーションなどをリセットできます。私の見解の中には気にしないものもありますが、他の人は本当に知る必要があります。

ストーリーボードを使用していますが、アプリのデリゲートファイルには標準機能がありますが、すべて空のボディを使用しています。たとえば、didFinishLaunchingWithOptionsはYESを返すだけで、他には何もしません。ストーリーボードは、私が推測するすべてを自動的に実行します。

では、空白の情報のないアプリデリゲートから、現在のViewControllerとどのように通信できますか?

18
David John

通知の使用をお勧めします。

アプリデリゲートのapplicationdidBecomeActiveメソッドに次のコードを入力します。

[[NSNotificationCenter defaultCenter] postNotificationName:@"appDidBecomeActive" object:nil];

現在アクティブなViewControllerのinitメソッドで、通知をサブスクライブします。

[[NSNotificationCenter defaultCenter] addObserver:self 
                                         selector:@selector(updateStuff)        
                                             name:@"appDidBecomeActive" 
                                           object:nil];

コントローラに「updateStuff」メソッドを実装すると、アプリがアクティブになったときに何でもできるようになります。

22

アプリデリゲートから通知を送信する代わりに、OSは監視可能な通知を自動的に送信します。

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(initSongInfo)
                                             name:UIApplicationDidBecomeActiveNotification
                                           object:nil];

もちろん、deallocメソッドの前または内部で、次のコマンドを呼び出して、監視を停止するようにしてください。

[[NSNotificationCenter defaultCenter] removeObserver:self 
                                                name:UIApplicationDidBecomeActiveNotification 
                                              object:nil];
55
Ben Baron

Swiftバージョン:

この行をviewDidLoadに追加できます

NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(viewDidBecomeActive), name: UIApplicationDidBecomeActiveNotification, object: nil)

func viewDidBecomeActive(){
    print("viewDidBecomeActive")
}
3
Rashwan L

appDelegateにはwindowプロパティがあり、そのウィンドウにはrootViewControllerプロパティがあります。ここでviewControllerを見つけることができます。

TabBarControllerを使用している場合、rootviewcontrollerはtabbarcontrollerになり、tabbarcontrollerのselectedViewControllerを呼び出して現在のviewControllerを取得できます。

UIViewController *rootViewController = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
if ([rootViewController isKindOfClass:[UITabBarController Class]])
    rootViewController = ((UITabBarController *)rootViewController).selectedViewController;
else if ([rootViewController isKindOfClass:[UINavigationController Class]])
    rootViewController = ((UINavigationController *)rootViewController).topViewController;

[rootViewController viewDidAppear];

ナビゲーションコントローラーまたはモーダルビューを使用したより複雑なビュー階層がある場合は、presentedViewControllerまたはtopViewControllerを呼び出すことができます。

0
Jesse Gumpo

さて、それはかなり壊滅的です。

皆さんは、メモリリークを引き起こす可能性があるため、イベントの登録/登録解除に注意を払う必要があります。

すべてを機能させるには、バックグラウンドイベントに署名したかどうかなど、登録ステータスを認識するフラグを設定する必要があります。ユーザーがViewControllerを表示したとき(別のユーザーから来た場合)、またはユーザーがホーム画面からView Controllerに来た場合は、イベントに登録する必要があることに注意してください。

ビューコントローラを別のコントローラに残す場合も、登録を解除する必要があります。

要するに:

Swift 4:

private var registeredToBackgroundEvents = false

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    registerToBackFromBackground()
}

/// register to back from backround event
private func registerToBackFromBackground() {
    if(!registeredToBackgroundEvents) {
        NotificationCenter.default.addObserver(self, 
        selector: #selector(viewDidBecomeActive), 
        name: UIApplication.didBecomeActiveNotification, object: nil)
        registeredToBackgroundEvents = true
    }
}

/// unregister from back from backround event
private func unregisterFromBackFromBackground() {
    if(registeredToBackgroundEvents) {
        NotificationCenter.default.removeObserver(self, 
        name: UIApplication.didBecomeActiveNotification, object: nil)
        registeredToBackgroundEvents = false
    }

}

@objc func viewDidBecomeActive(){
    logicManager.onBackFromStandby()
}


override func viewWillDisappear(_ animated: Bool) {
    unregisterFromBackFromBackground()
}
0
Oz Shabat

どのViewControllerが最新であるかを追跡しようとするのではなく、AppDelegateからNSNotificationを送信し、ViewControllerでサブスクライブすることができます。これにより、ViewControllerはviewDidAppearを呼び出す必要があるかどうかを追跡します。

0
Joseph DeCarlo