[解決済み】アプリがバックグラウンドから戻ってきたときに、viewWillAppearが呼ばれないのはなぜですか?
質問
アプリを書いているのですが、ユーザーが電話で話しながらアプリを見ている場合、表示を変更する必要があります。
以下のメソッドを実装しました。
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
NSLog(@"viewWillAppear:");
_sv.frame = CGRectMake(0.0, 0.0, 320.0, self.view.bounds.size.height);
}
しかし、アプリがフォアグラウンドに戻ったときに呼び出されることはないのです。
実装できることは分かっている。
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(statusBarFrameChanged:) name:UIApplicationDidChangeStatusBarFrameNotification object:nil];
が、私はこれをやりたくない。むしろ、viewWillAppear:メソッドにレイアウト情報をすべて入れて、すべての可能なシナリオを処理できるようにしたいのです。
applicationWillEnterForeground: から viewWillAppear: を呼び出そうとしたこともありますが、その時点で現在のビューコントローラーがどれなのか特定できないようです。
どなたか適切な対処法をご存じないでしょうか?私は明白な解決策を見逃していると確信しています。
解決方法は?
方法
viewWillAppear
は、自分のアプリケーションで何が起こっているかという文脈で捉えるべきであり、他のアプリケーションから切り替えたときに自分のアプリケーションが前景に置かれるという文脈で捉えるべきではありません。
つまり、誰かが他のアプリケーションを見たり電話をかけたりした後、さっきまでバックグラウンドだった自分のアプリに切り替えた場合、自分のアプリを離れたときにすでに見えていたUIViewControllerはいわば「気にしない」わけで、自分に関する限りは決して消えておらず、まだ見えている状態なのだから
viewWillAppear
は呼び出されません。
を呼び出さないことをお勧めします。
viewWillAppear
これは特定の意味を持っており、それを覆すべきではありません。同じ効果を得るためにできるリファクタリングは次のようなものです。
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self doMyLayoutStuff:self];
}
- (void)doMyLayoutStuff:(id)sender {
// stuff
}
次に
doMyLayoutStuff
を適切な通知から削除します。
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(doMyLayoutStuff:) name:UIApplicationDidChangeStatusBarFrameNotification object:self];
ところで、どれが「現在の」UIViewControllerなのか、すぐにわかるような方法はないんだ。例えば、UINavigationControllerのデリゲートメソッドがあり、そこにUIViewControllerが提示されたときにそれを見つけることができる。このようなものを使って、最新のUIViewControllerが提示されたことを追跡することができる。
更新情報
UIをレイアウトする際に、様々なビットに適切なオートサイズ・マスクを適用すれば、UIの「手動」レイアウトに対処する必要さえない場合もあります...。
関連
-
[解決済み】 libc++abi.dylib: NSException 型のキャッチできない例外で終了する (lldb)
-
[解決済み] Xcode は、[バンドル ID] に一致する iOS App Store プロビジョニングプロファイルを見つけられませんでした。
-
[解決済み] ペン先を読み込んだが、「表示」コンセントが設定されていない
-
[解決済み] iPhoneが使用できません。デバイスを再接続してください
-
[解決済み] <UITabBarController: 0x197870> の外観遷移の開始/終了の呼び出しがアンバランスである。
-
[解決済み] ブリッジングヘッダ用のプリコンパイルヘッダの発行に失敗しました。
-
[解決済み] ERROR ITMS-9000: "Redundant Binary Upload. 列車 '1.0' のビルドバージョン '1.0' のバイナリアップロードが既に存在します" と表示されました。
-
[解決済み] viewDidLoad()は何のためにあるのですか?[重複]する
-
[解決済み] アプリケーションは、アプリケーション起動の最後にルートビューコントローラーを持つことが期待される
-
[解決済み] Xcode 6: iOS 8.1 The Developer Disk Imageをマウントできませんでした。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Xcode 10.2.1 Command PhaseScriptExecutionが0以外の終了コードで失敗した。
-
[解決済み】arm64アーキテクチャの未定義シンボルについて
-
[解決済み] Xcode は、[バンドル ID] に一致する iOS App Store プロビジョニングプロファイルを見つけられませんでした。
-
[解決済み] ペン先を読み込んだが、「表示」コンセントが設定されていない
-
[解決済み] 「シミュレータで実行すると、「インストールされているプロビジョニングプロファイルが、インストールされているiOS署名アイデンティティと一致しません。
-
[解決済み] <UITabBarController: 0x197870> の外観遷移の開始/終了の呼び出しがアンバランスである。
-
[解決済み] 警告 xcode 6 で暗黙の変換により整数の精度が失われる
-
[解決済み] 新しいアウトレット接続を挿入できませんでした。という名前のクラスの情報が見つかりませんでした。
-
[解決済み] UILabelにスペース/パディングを追加する
-
[解決済み] バックグラウンドからアプリを開くとViewDidAppearが呼ばれない