私は奇妙なバグに直面しています。それはiOS10でのみ発生します。
複数の画面を持つアプリケーションがあり、各画面はnavigationBar
のviewWillAppear
に色を付けています。そのため、次の画面に進むと、適切に色付けされます。
ただし、iOS 10でテストすると、前の画面に戻ると突然次の動作が見られます。前の画面が表示されても、navigationBar
は前の画面の色のままで、適切な色に点滅します。 viewWillAppear
はどういうわけかviewDidAppear
のように動作するように見えます。
関連コード:
ViewController:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[ViewControllerPainter Paint:self withBackground:[UIColor whiteColor] andForeground:[UIColor blackColor] andIsLight:true];
}
画家:
+ (void)Paint:(UIViewController *)controller withBackground:(UIColor *)backgroundColor andForeground:(UIColor *)foregroundColor andIsLight:(bool)isLight
{
controller.navigationController.navigationBar.opaque = true;
controller.navigationController.navigationBar.translucent = false;
controller.navigationController.navigationBar.tintColor = foregroundColor;
controller.navigationController.navigationBar.barTintColor = backgroundColor;
controller.navigationController.navigationBar.backgroundColor = backgroundColor;
controller.navigationController.navigationBar.barStyle = isLight ? UIBarStyleDefault : UIBarStyleBlack;
controller.navigationController.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName: foregroundColor};
}
これはバグですか?これを修正するために私にできることはありますか?とてもイライラします。
iOS 10 SDKリリースノート に従って変更されたものは次のとおりです。
IOS 10では、UIKitは、UINavigationBar、UITabBar、およびUIToolbarのバックグラウンド管理を更新および統合しました。特に、これらのビューの背景プロパティへの変更(背景や影の画像、バースタイルの設定など)により、新しい背景の外観を解決するためにバーのレイアウトパスが開始される場合があります。
特に、これは、-[UIView layoutSubviews]、-[UIView updateConstraints]、-[UIViewController willLayoutSubviews]、-[UIViewController didLayoutSubviews]、-[UIViewControllerupdateViewConstraints内のこれらのバーの背景の外観を変更しようとすることを意味します]、またはレイアウトに応答して呼び出される他のメソッドは、レイアウトループを引き起こす可能性があります。
したがって、問題は、viewWillAppear
がレイアウト変更の結果として呼び出されるため、前述のレイアウトループをトリガーしていることのようです。
私の簡単な修正は、popViewControllerAnimated
とpushViewController
をオーバーライドし、navigationBar
のサブクラスのUINavigationController
バックグラウンドを更新することでした。外観は次のとおりです。
override func popViewControllerAnimated(animated: Bool) -> UIViewController? {
let poppedViewController = super.popViewControllerAnimated(animated)
// Updates the navigation bar appearance
updateAppearanceForViewController(nextViewController)
return poppedViewController
}
override func pushViewController(viewController: UIViewController, animated: Bool) {
super.pushViewController(viewController, animated: animated)
// Updates the navigation bar appearance
updateAppearanceForViewController(viewController)
}
私の推測では、popViewControllerAnimated
とpushViewController
は、レイアウト変更の結果としてOSによって呼び出されるのではなく、タッチイベントによって呼び出されるために機能します。したがって、navigationBar
の背景を更新する別の場所を見つけたい場合は、この点に注意してください。
私はこれを次のように修正する必要がありました:
self.navigationController.navigationBarHidden = YES;
self.navigationController.navigationBarHidden = NO;
このようにして、popviewcontrollerまたはpushviewcontrollerをオーバーライドする必要はありません。基本的に、ナビゲーションバーをトリガーして再描画します。
これほど重要な何かを壊す新しいバージョンのOSをプッシュする方法はまだ面倒です。
willMoveToParentViewController
を使用してみてください。これは、UINavigationController
メソッドをオーバーライドするのと同じ効果がありますが、面倒なことはありません。