2

I am implementing the features for the management of the Dark Mode of iOS 13 in my app .. I have a problem for the background of my ViewController.

My view controller has a background gradient color obtained with CAGradientLayer.

I managed to change the colors that make up the gradient based on the user's choice when it goes from Dark Mode ---> Light Mode and Light Mode ---> Dark Mode ..

My problem is that when the user sends in background my app to go to the control center and change the mode, the colors of the gradient I used for my background color do not change immediately ...

To get the gradient color changes the user must close the app and reopen it.

A really bad User Experince so I wanted to ask you how to solve this problem ...

This is what I use to change the colors of my gradient based on the user-selected iOS mode

- (void)viewDidLoad {
    [super viewDidLoad];

    [self setupBackground];
}

- (void)setupBackground {

    UIColor *secondaryColor = self.view.traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark ? UIColor.customRedColor : UIColor.customGreenColor;

    CAGradientLayer *gradient = [CAGradientLayer layer];

    gradient.frame = UIApplication.sharedApplication.windows.firstObject.bounds;
    gradient.colors = @[(id)UIColor.customBlueColor.CGColor, (id)secondaryColor.CGColor];
    gradient.locations = @[@0.1, @0.9];

    [self.view.layer insertSublayer:gradient atIndex:0];
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
kAiN
  • 2,559
  • 1
  • 26
  • 54

2 Answers2

2

You should implement the traitCollectionDidChange and have it update your background:

- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
    [super traitCollectionDidChange:previousTraitCollection];

    if (@available(iOS 13.0, *)) { // Needed if your app supports iOS 12
        if ([self.traitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection]) {
            [self setupBackground];
        }
    }
}

Of course this means that setupBackground will be called many times. So you should update it so it doesn't add a new layer each time.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • Perfect thank you .. I was thinking of a different solution .. Tell me if I'm wrong .. If I create two backgorund images and insert them in the asset (both for the excuse and for the clear one) it is not better? I would avoid double call problems on the right methods? – kAiN Sep 27 '19 at 22:39
  • The gradient is better. With images it gets messy as the size of the view changes such as rotating the device or supporting split mode on iPads. – rmaddy Sep 27 '19 at 22:41
  • I tried to implement the method you suggested but when I go to the background to set the dark mode to Settings on my device the background doesn't change :( – kAiN Sep 27 '19 at 22:43
  • Is `setupBackground` called? Is it getting the right colors? Are you sure you have just the one layer in the view? – rmaddy Sep 27 '19 at 22:46
  • Above the view controller (the gradient is applied to its background) I only have another 1 view 5 label a 1 button and a 1 switch. The setup method [self setupBackground]; is called in view did load to indicate the gradient the first time and then called in traitCollectionDidChange – kAiN Sep 27 '19 at 22:51
  • You didn't answer my other questions. Use the debugger and see what's really happening. – rmaddy Sep 27 '19 at 22:52
  • Yes the "setupBackground" method is called every time .. The colors are correct the problem is that it does not change according to the set mode ... the first gradient selected always remains – kAiN Sep 27 '19 at 22:57
  • Make sure the only gradient layer in the view is new gradient layer with the latest colors. – rmaddy Sep 27 '19 at 22:58
0

kAiN,

There is a lot of dificulties to implement Dark Mode with ObjC on iOS13, but fortunatily a group of Devs e Designers made a realy easy way of doing it:

https://medium.com/flawless-app-stories/implementing-dark-mode-on-ios-d195cac098de

Best regards. o/