Как изменить UIColor в соответствии с UserInterfaceStyle (темный режим/светлый режим) в расширении UIView в swift [5+]?

Я создавал метод в расширении UIView, и мне нужно было изменить UIColor в соответствии с UIUserInterfaceStyle, т.е. отдельный UIColor для интерфейса темного и светлого режимов.

Обычно в методе UIViewController класса traitCollectionDidChange срабатывает всякий раз, когда изменяется UIUserInterfaceStyle, и мы можем определить текущий стиль пользовательского интерфейса,

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
    super.traitCollectionDidChange(previousTraitCollection)
    DispatchQueue.main.async { [weak self] in
        guard let self = self else { return }
        self.changeUIWithUserInterface(style: self.traitCollection.userInterfaceStyle)
    }
}

Но расширение UIView не имеет метода traitCollectionDidChange, который можно запустить.

так как я могу изменить UIColor в соответствии с UIUserInterfaceStyle в расширении UIView?
Я понял это и решил опубликовать это для коллег-разработчиков.

Надеюсь, поможет :)

Почему вы используете DispatchQueue для UI-Work? Не имеет никакого смысла

baronfac 02.01.2023 11:10

Метод changeUIWithUserInterface изменяет пользовательский интерфейс всякий раз, когда он вызывается, поэтому я поместил его в DispatchQueue.main.., я что-то здесь упускаю, @baronfac

Nayan Dave 02.01.2023 11:39

Да. Он всегда будет вызываться в основном потоке

baronfac 02.01.2023 16:08
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
89
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Метод ниже работает как шарм для меня!
Он срабатывает всякий раз, когда traitCollection изменяется..
Он может работать с любым расширением различных компонентов пользовательского интерфейса.

UIColor.init { (trait) -> UIColor in
    return trait.userInterfaceStyle == .dark ? darkModeColor : lightModeColor
}

Вы должны проверить iOS 13+, если вы работаете с поддержкой версий iOS ниже 13, что вы можете легко проверить

if #available(iOS 13.0, *) {
    //Dark mode is supported 
    self.backgroundColor = UIColor.init { (trait) -> UIColor in
        return trait.userInterfaceStyle == .dark ? darkModeColor : lightModeColor
    }
} else {
    //Earlier version of iOS, which does not suppport dark mode.
    self.backgroundColor = lightModeColor
}

Ссылка: Спасибо за ответ @ElanoVasconcelos

Вы можете установить UIColor как простую переменную, которая автоматически изменяется при изменении traitCollection:

struct ColorPalette {

public static var subtitleColor: UIColor = {
    if #available(iOS 13, *) {
        return UIColor { (UITraitCollection: UITraitCollection) -> UIColor in
            if UITraitCollection.userInterfaceStyle == .dark {
                return UIColor.lightText
            } else {
                return .darkGray
            }
        }
    } else {
        /// Return a fallback color for iOS 12 and lower.
        return .darkGray
    }
  }()
}

Использование:

label.textColor = ColorPalette.subtitleColor

Да, сэр, вы правы, но это следующий шаг, моя проблема заключалась в том, что я не могу изменить цвет в методе, созданном в расширении UIView... вы также используете то же самое (метод инициализации UIColor с traitcollection)..который я не знал о ... так что подумал, что это может помочь парню ... в любом случае спасибо, что поделились!

Nayan Dave 02.01.2023 14:22

Другие вопросы по теме