Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

traitCollectionDidChange being called multiple times when only going to background

I have found that when putting app into background the traitCollectionDidChange method is being called twice and showing that trait collections differ when actually no changes have been made.

- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection;

To figure out if appearance style has been switched between Light & Dark mode we have used the hasDifferentColorAppearanceComparedToTraitCollection method.

BOOL hasUserInterfaceStyleChanged = [previousTraitCollection
                                     hasDifferentColorAppearanceComparedToTraitCollection:self.traitCollection];

The problem is that this is always true, and for whatever reason trait collections are different when nothing was changed. See below UserInterfaceStyle is actually different when in reality it isn't.

First Trigger:

previousTraitCollection:

<UITraitCollection: 0x280228c00; UserInterfaceIdiom = Phone, DisplayScale = 2, DisplayGamut = P3, HorizontalSizeClass = Compact, VerticalSizeClass = Regular, UserInterfaceStyle = Light, UserInterfaceLayoutDirection = LTR, ForceTouchCapability = Unavailable, PreferredContentSizeCategory = L, AccessibilityContrast = Normal, UserInterfaceLevel = Base>

self.traitCollection:

<UITraitCollection: 0x28023b600; UserInterfaceIdiom = Phone, DisplayScale = 2, DisplayGamut = P3, HorizontalSizeClass = Compact, VerticalSizeClass = Regular, UserInterfaceStyle = Dark, UserInterfaceLayoutDirection = LTR, ForceTouchCapability = Unavailable, PreferredContentSizeCategory = L, AccessibilityContrast = Normal, UserInterfaceLevel = Base>

Second Trigger:

previousTraitCollection:

<UITraitCollection: 0x28023b600; UserInterfaceIdiom = Phone, DisplayScale = 2, DisplayGamut = P3, HorizontalSizeClass = Compact, VerticalSizeClass = Regular, UserInterfaceStyle = Dark, UserInterfaceLayoutDirection = LTR, ForceTouchCapability = Unavailable, PreferredContentSizeCategory = L, AccessibilityContrast = Normal, UserInterfaceLevel = Base>

self.traitCollection:

<UITraitCollection: 0x28027d800; UserInterfaceIdiom = Phone, DisplayScale = 2, DisplayGamut = P3, HorizontalSizeClass = Compact, VerticalSizeClass = Regular, UserInterfaceStyle = Light, UserInterfaceLayoutDirection = LTR, ForceTouchCapability = Unavailable, PreferredContentSizeCategory = L, AccessibilityContrast = Normal, UserInterfaceLevel = Base>

On the second trigger now trait collections have been reversed but still differ. In this scenario the very first trait collection and the very last trait collection are the correct ones.

Is this a bug on Apple's end? Why is traitCollectionDidChange being called twice when just putting app into background.

like image 667
Evan Avatar asked Dec 08 '22 10:12

Evan


2 Answers

This is actually a feature: iOS is doing multiple snapshots of your app's UI that will be presented in the App Switcher. And since the user could change to Dark Mode while your app is in the background, iOS does snapshots in both interface styles to always show the correct one.

like image 54
Frank Schlegel Avatar answered Jan 19 '23 00:01

Frank Schlegel


check if UIApplication.shared.applicationState != .background to avoid doing stuff while app snapshots are being taken when going to background

like image 33
Tomer Even Avatar answered Jan 19 '23 00:01

Tomer Even