Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is iOS not overriding background color if I use a custom color from xib?

Tags:

xcode

ios

swift

I have a xib. I have a view controller that loads the xib and adds it to its subview. The xib has the background color set from the xib file (from interface) to a CUSTOM COLOR SET from assets (created by me). Everything works fine.

Now, inside my view controller, in viewDidLoad I want to override that background color with something else. The problem I found and it replicates 100% is that overriding doesn't do anything, unless I do it in viewDidAppear.

So to sum up...

  • custom color background set from xib... overriding in viewDidLoad not working, overriding in viewDidAppear working

  • Xcode default color background set from xib (any other color except from assets custom colors)... overriding in viewDidLoad WORKS...

Why in the first case I cannot override the color and in the second I can?

Is there a hidden feature that I'm missing here? You simply cannot override a view background color in viewDidLoad if the color set from xib is custom color, but if it's any other color... like white, red, black or w/e Xcode already has everything works as expected.

If it has any impact... this view controller I'm talking about gets pushed on the navigation stack. But I don't see how this can have any impact.


Reproduction Steps:

To replicate this... create a new sample project... that only has one view controller in it. Next add a custom color via assets -> new color set. Set the view controllers view background color from storyboard to the newly added color set. Then inside viewDidLoad change the background color of the view to something else... you will notice if you run the app it WON'T CHANGE if in storyboard there is a custom color set as background.

Somehow the background custom color set from storyboard overrides happen behind the scenes after viewDidLoad and before viewDidAppear.

like image 684
Alin Lipan Avatar asked Sep 19 '19 08:09

Alin Lipan


2 Answers

Faced with this issue recently

I had xib file for table cell and custom colors in xcasset. Colors are single appearance (dark mode not supported). In cell swift class I have bool variable with didSet, where few outlets are modified: view.backgroundColor and label.textColor. Their values are based on variable value. There are ternar conditions so I was sure that color will be selected correctly.

On devices with iOS 12 (checked on 12.1 and 12.4 real and simulators) color didn't change at start but only after cell reuse.

After finding this question and few experiments, I have found that: Setting custom color in xib file (no matter, if they have dark version or not) was performed after my didSet block and overrides my conditions results. And since I have set one of possible color in xib, I though that problem in data.

So I have reset outlets colors to default in xib and now it works In case if you have to display some default color before some conditions, I guess putting it in init methods (awakeFromNib, viewDidLoad etc) should work

This bug was fixed in 13.0+

Duplicating answer from https://developer.apple.com/forums/thread/649009

like image 149
Viktor Avatar answered Oct 17 '22 14:10

Viktor


I come late but have more info for future readers. I just met this bug in my App for iOS 11 and iOS 12. The bug is solved by Apple since iOS 13.0. So if you support previous version, you still need to apply the workaround from @AlanS, or not use custom colors in storyboard and xib :

func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()

    if #available(iOS 13.0, *) {
        // Fix iOS 12 storyboard color bug.
    } else {
        view.backgroundColor = UIColor.black
    }
}
like image 35
vmeyer Avatar answered Oct 17 '22 15:10

vmeyer