简体   繁体   English

状态恢复期间的UIAppearance错误

[英]UIAppearance bug during state restoration

Update 更新资料

Matt rightly pointed out that my original project had an error with state restoration. 马特正确地指出,我的原始项目在状态恢复方面存在错误。 However, even after it is removed, I am able to reproduce an issue as long as I am using a table view inside a navigation controller and trying to set isTranslucent property of UINavigationBar to false via an appearance proxy. 但是,即使将其删除,只要我在导航控制器中使用表格视图并尝试通过外观代理将UINavigationBar isTranslucent属性设置为false ,就能够重现问题。


For some reason, when iOS restores state, UIAppearance overrides values set in viewDidLoad . 出于某种原因,当iOS恢复状态时,UIAppearance会覆盖viewDidLoad设置的值。 It causes me a lot of headaches, and I would like to know how to solve this issue. 这让我很头疼,我想知道如何解决这个问题。 I view it as a bug. 我将其视为错误。

Here is a small project I created on GitHub to illustrate this issue. 是我在GitHub上创建的一个小项目,用于说明此问题。 When you launch it for the first time, the label's font in ViewController is correctly set to 22 points. 首次启动时, ViewController标签的字体正确设置为22点。 However, if you trigger state restoration, it will be 12 points because of the appearance method in willFinishLaunching . 但是,如果触发状态恢复,由于willFinishLaunching中的出现方法,它将为12点。

In fact, the cause of this issue is not UILabel.appearance(whenContainedInInstancesOf: [UITableViewCell.self]).font = UIFont.systemFont(ofSize: 12) as I originally thought. 实际上,此问题的原因不是我最初想到的UILabel.appearance(whenContainedInInstancesOf: [UITableViewCell.self]).font = UIFont.systemFont(ofSize: 12) Instead, UINavigationBar.appearance(whenContainedInInstancesOf: [GLXNavigationController.self]).isTranslucent = false causes such a behaviour. 而是, UINavigationBar.appearance(whenContainedInInstancesOf: [GLXNavigationController.self]).isTranslucent = false会导致这种行为。 You can easily verify it yourself. 您可以轻松地自己验证。

One way to solve this is to set the font again in layoutSubviews because appearance proxies are applied just before layoutSubviews is called. 解决此问题的一种方法是在layoutSubviews再次设置字体,因为外观代理是在调用layoutSubviews之前应用的。 However, I do not like this approach. 但是,我不喜欢这种方法。

Another possible solution is to set isTranslucent manually for each navigation controller. 另一种可能的解决方案是为每个导航控制器手动设置isTranslucent It is a solution I am opting for, but I still feel that there is a bug with appearance proxy. 这是我选择的解决方案,但我仍然觉得外观代理存在错误。 At a minimum, we should expect consistent behaviour between initial launch and state restoration. 至少,我们应该期望初始启动和状态恢复之间的行为一致。

Any help is much appreciated. 任何帮助深表感谢。

You are doing state restoration wrong: 您正在做错误的状态还原:

  • Change didFinishLaunchingWithOptions to willFinishLaunchingWithOptions . didFinishLaunchingWithOptions更改为willFinishLaunchingWithOptions

  • And make sure that willFinishLaunchingWithOptions contains a call to the window to makeKeyAndVisible , even if it contains nothing else. 并确保willFinishLaunchingWithOptions包含对makeKeyAndVisible窗口的调用,即使该窗口不包含其他任何内容。

That, along with implementations of shouldSaveApplicationState and shouldRestoreApplicationState , constitutes the rock-bottom boilerplate needed for any implementation of state saving and restoration. 这与shouldSaveApplicationStateshouldRestoreApplicationState实现shouldRestoreApplicationState ,构成了状态保存和恢复的任何实现所需的底层模板。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM