私はここでトリックを逃しているように感じます...
ApplicationDidBecomeActiveが呼び出されたときに、現在アクティブなView ControllerでviewDidLoadまたはviewDidAppearを呼び出したいだけなので、アプリをバックグラウンドから再起動したときに、アニメーションなどをリセットできます。私の見解の中には気にしないものもありますが、他の人は本当に知る必要があります。
ストーリーボードを使用していますが、アプリのデリゲートファイルには標準機能がありますが、すべて空のボディを使用しています。たとえば、didFinishLaunchingWithOptionsはYESを返すだけで、他には何もしません。ストーリーボードは、私が推測するすべてを自動的に実行します。
では、空白の情報のないアプリデリゲートから、現在のViewControllerとどのように通信できますか?
通知の使用をお勧めします。
アプリデリゲートのapplicationdidBecomeActiveメソッドに次のコードを入力します。
[[NSNotificationCenter defaultCenter] postNotificationName:@"appDidBecomeActive" object:nil];
現在アクティブなViewControllerのinitメソッドで、通知をサブスクライブします。
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(updateStuff)
name:@"appDidBecomeActive"
object:nil];
コントローラに「updateStuff」メソッドを実装すると、アプリがアクティブになったときに何でもできるようになります。
アプリデリゲートから通知を送信する代わりに、OSは監視可能な通知を自動的に送信します。
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(initSongInfo)
name:UIApplicationDidBecomeActiveNotification
object:nil];
もちろん、deallocメソッドの前または内部で、次のコマンドを呼び出して、監視を停止するようにしてください。
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIApplicationDidBecomeActiveNotification
object:nil];
Swiftバージョン:
この行をviewDidLoadに追加できます
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(viewDidBecomeActive), name: UIApplicationDidBecomeActiveNotification, object: nil)
func viewDidBecomeActive(){
print("viewDidBecomeActive")
}
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を呼び出すことができます。
さて、それはかなり壊滅的です。
皆さんは、メモリリークを引き起こす可能性があるため、イベントの登録/登録解除に注意を払う必要があります。
すべてを機能させるには、バックグラウンドイベントに署名したかどうかなど、登録ステータスを認識するフラグを設定する必要があります。ユーザーが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()
}
どのViewControllerが最新であるかを追跡しようとするのではなく、AppDelegateからNSNotificationを送信し、ViewControllerでサブスクライブすることができます。これにより、ViewControllerはviewDidAppearを呼び出す必要があるかどうかを追跡します。