ViewWillAppear中的导航栏着色在iOS 10中发生得太晚了

Pet*_*rdk 19 viewwillappear ios10

我面临一个奇怪的错误,只在iOS 10上发生.

我有几个画面的应用程序,每个屏幕的颜色navigationBarviewWillAppear.因此,当您进入下一个屏幕时,它将被正确着色.

但是,在iOS 10上进行测试时,我会在返回上一个屏幕时突然看到以下行为:当前一个屏幕出现时,navigationBar仍然具有上一个屏幕的颜色,然后闪烁到正确的颜色.它几乎看起来像viewWillAppear某种行为viewDidAppear.

相关代码:

视图控制器:

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [ViewControllerPainter paint:self withBackground:[UIColor whiteColor] andForeground:[UIColor blackColor] andIsLight:true];

}
Run Code Online (Sandbox Code Playgroud)

画家:

+ (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};
}
Run Code Online (Sandbox Code Playgroud)

这是一个错误吗?我能解决这个问题吗?这非常令人沮丧.

小智 23

以下是根据iOS 10 SDK发行说明所做的更改:

在iOS 10中,UIKit为UINavigationBar,UITabBar和UIToolbar更新并统一了后台管理.特别是,对这些视图的背景属性(例如背景或阴影图像或设置条形样式)的更改可能会启动条形图的布局传递以解析新的背景外观.
特别是,这意味着尝试更改这些条形图的背景外观 - [UIView layoutSubviews], - [UIView updateConstraints], - [UIViewController willLayoutSubviews], - [UIViewController didLayoutSubviews], - [UIViewController updateViewConstraints]或任何其他响应布局而调用的方法可能会导致布局循环.

所以问题似乎viewWillAppear是触发了上面提到的布局循环,因为它是由于布局改变而调用的: 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)
}
Run Code Online (Sandbox Code Playgroud)

我的猜测是,它的作品,因为popViewControllerAnimatedpushViewController没有被OS作为布局变化的结果叫,而是由一个触摸事件.因此,如果您想找到另一个地方来更新您的navigationBar背景,请记住这一点.


Vla*_*lad 16

我不得不解决这个问题:

self.navigationController.navigationBarHidden = YES;
self.navigationController.navigationBarHidden = NO;
Run Code Online (Sandbox Code Playgroud)

这样您就不必重写popviewcontroller或pushviewcontroller.它基本上是触发导航栏重绘.

它仍然很烦人,他们怎么能推出一个新版本的操作系统,打破这个重要的东西.


小智 7

尝试使用willMoveToParentViewController,提供与重写UINavigationController方法相同的效果,但没有麻烦.