traitCollectionDidChange вызывается несколько раз только при переходе в фоновый режим

#ios #objective-c #ios-darkmode

#iOS #objective-c #ios-darkmode

Вопрос:

Я обнаружил, что при переводе приложения в фоновый режим метод traitCollectionDidChange вызывается дважды и показывает, что коллекции признаков отличаются, когда на самом деле никаких изменений не было сделано.

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

Чтобы выяснить, был ли стиль внешнего вида переключен между светлым и темным режимами, мы использовали метод hasdifferentcolorappearancecomparredtotraitcollection.

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

Проблема в том, что это всегда верно, и по какой-либо причине коллекции признаков отличаются, когда ничего не было изменено. Смотрите ниже, пользовательский интерфейс на самом деле отличается, когда на самом деле это не так.

Первый триггер:

Предыдущая Stratitcollection:

 <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>
  

Второй триггер:

Предыдущая Stratitcollection:

 <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>
  

При втором запуске теперь коллекции признаков были изменены местами, но все еще отличаются. В этом сценарии самая первая коллекция признаков и самая последняя коллекция признаков являются правильными.

Это ошибка со стороны Apple? Почему traitCollectionDidChange вызывается дважды при простом переводе приложения в фоновый режим.

Ответ №1:

На самом деле это особенность: iOS делает несколько снимков пользовательского интерфейса вашего приложения, которые будут представлены в App Switcher. И поскольку пользователь может перейти в темный режим, пока ваше приложение работает в фоновом режиме, iOS делает снимки в обоих стилях интерфейса, чтобы всегда показывать правильный.

Комментарии:

1. Наверняка здесь все еще что-то не так? Есть ли правильный способ точно определить, что режим внешнего вида изменился вместо этого, чтобы мы запускали обновления только при крайней необходимости?

2. Мне кажется правильным: система делает снимок экрана вашего светлого пользовательского интерфейса, переключается на темный (первый триггер), делает снимок экрана (вне экрана) и переключается обратно на светлый (второй триггер). И я думаю, было бы неплохо соответствующим образом обработать этот сценарий и не пытаться избежать его. Или у вас возникли проблемы?

Ответ №2:

проверьте, UIApplication.shared.applicationState != .background чтобы избежать выполнения каких-либо действий во время создания снимков приложения при переходе в фоновый режим