Цвет тени UIView не меняется

У меня есть UIView, и я установил для него shadowPath вот так:

func addShadow() {
    let cornerRadius: CGFloat = self.containerView.frame.height/2
    self.containerView.layer.shadowPath = UIBezierPath(roundedRect: self.containerView.frame, cornerRadius: cornerRadius).cgPath
    self.containerView.layer.shadowRadius = cornerRadius
    self.containerView.layer.shadowOffset = .zero
    self.containerView.layer.shadowOpacity = 0.2
    self.containerView.layer.cornerRadius = cornerRadius
    self.containerView.layer.shadowColor = UIColor(named: "whiteColor")?.cgColor
}

А это whiteColor:

введите описание изображения здесь

И теперь моя проблема

Когда я меняю внешний вид телефона, цвет shadowPath не меняется автоматически. Что мне делать, чтобы цвет стал динамичным?


person Arash Etemad    schedule 25.09.2019    source источник
comment
Делайте все свои цветовые решения в layoutSubview или viewDidLayoutSubviews. Затем вы устанавливаете цвет динамической переменной, которая будет вычислять ее значение на основе traitCollection.userInterfaceStyle.   -  person andromedainiative    schedule 25.09.2019
comment
@andromedainiative Вы уверены, что это лучший способ? У меня много видов с тенью. Правильно ли установить их все в layoutSubView?   -  person Arash Etemad    schedule 25.09.2019
comment
Я имею в виду, что я не знаю универсального решения «серебряной пули». В итоге мы переместили все наши настройки цвета этими методами. Вы можете прочитать больше об этом здесь. Если вы не используете один и тот же контроллер представления в каждом представлении, вам придется вручную обновить цвета. developer.apple.com/documentation/appkit/   -  person andromedainiative    schedule 26.09.2019
comment
@andromedainiative хороший документ, спасибо   -  person Arash Etemad    schedule 26.09.2019


Ответы (3)


Все свойства слоя не реагируют на изменение цвета автоматически (из-за преобразования в CGColor).

Вместо этого реагируйте на изменения коллекции признаков и повторно устанавливайте свойства при изменении внешнего вида цвета:

override open func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
    super.traitCollectionDidChange(previousTraitCollection)

    if #available(iOS 13, *), self.traitCollection.hasDifferentColorAppearance(comparedTo: previousTraitCollection) {
        // re-set your properties here
    }
}
person Frank Schlegel    schedule 25.09.2019
comment
Тогда я должен переопределять этот метод в каждом ViewController ?! Мне нужно более универсальное решение! - person Arash Etemad; 25.09.2019
comment
Только вы установили свойства слоя. Но да, это больно. Я создал BaseView, который предоставляет UIColor свойства для всех этих свойств слоя и обрабатывает изменения внешнего вида. Но теперь у меня получилось 4 разных BaseView для кнопок, ячеек табличного представления и т. Д. ???? - person Frank Schlegel; 25.09.2019
comment
Пожалуйста, позвоните super.traitCollectionDidChange - person Umair; 22.07.2020

добавьте self.view.layoutIfNeeded() в свою функцию. Это может решить вашу проблему. В качестве альтернативы вы добавите цвет в viewDidLayoutSubviews.

person Nahid Raihan    schedule 25.09.2019
comment
self.view.layoutIfNeeded() не сработало, и я думаю, что переопределение viewDidLayoutSubViews не самое лучшее! потому что я должен переопределить этот метод в каждом ViewController! Мне нужно более универсальное решение! - person Arash Etemad; 25.09.2019
comment
Лучшее универсальное решение, которое я могу придумать, - это создать базовый класс представления, который обрабатывает изменения характеристик и выводит из него все представления, которые в нем нуждаются. - person Frank Schlegel; 25.09.2019
comment
Можете ли вы запустить его в основном потоке? это может быть работа. Я имею в виду использование- func addShadow () {DispatchQueue.main.async {// здесь ваш код}} - person Nahid Raihan; 25.09.2019
comment
@NahidRaihan ничего не случилось! - person Arash Etemad; 25.09.2019
comment
1. откуда вы вызывали эту функцию? 2. Добавьте начальную строку self.view.layoutIfNeeded () в метод и добавьте еще раз перед завершением. - person Nahid Raihan; 25.09.2019
comment
добавьте это в viewWillAppear() пожалуйста. - person Nahid Raihan; 25.09.2019

Вот что сработало для меня - это смесь ответа Фрэнка Шлегеля и ответ на вопрос cgColor


override open func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {

   if #available(iOS 13, *), self.traitCollection.hasDifferentColorAppearance(comparedTo: previousTraitCollection) {

       SubmissionOptionsMenu.layer.shadowColor = 
              UIColor.label.resolvedColor(with: self.traitCollection).cgColor
   }
}
person Curtain Call LLC    schedule 14.11.2019