Цвет оттенка UIBarButtonItem не работает

Недавно я заметил, что поведение свойства tintColor значительно изменилось в одном из последних обновлений iOS 10.

У меня был код, который раньше работал отлично, а теперь вообще не работает.

В одном из моих приложений у меня есть коллекция UIBarButtonItem, которые добавляются в массив toolbarItems контроллера представления. Они нормально отображаются.

Однако в какой-то момент я хочу изменить цвет оттенка определенных элементов в ответ на действие пользователя. Код тривиален:

flagButton.tintColor = [UIColor redColor];

Раньше этот код работал, а теперь не работает! Я проверил, что ссылка на UIBarButtonItem существует и что эта строка кода выполняется. Однако цвет оттенка не меняется должным образом.

В описании свойства tintColor сказано:

Чтобы обновить отрисовку подпредставления при изменении этого свойства, переопределите метод tintColorDidChange().

Я попытался добавить метод tintColorDidChange, но он не вызывается. На данном этапе я предполагаю, что после изменения tintColor моя кнопка не обновляется автоматически.

Может ли кто-нибудь помочь найти способ обновить его вручную? Кнопка стандартная UIBarButtonItem с изображением.

Обновление 1

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

Обновление 2

Благодаря подсказке Мэтта я смог найти источник проблемы. Это было вызвано кодом, который выполнялся при запуске приложения:

[[UITableViewCell appearance] setTintColor:[ColourTheme sharedTheme].navBackground];

Теперь я совершенно озадачен тем, почему эта строка вызвала проблемы с оттенком UIBarButtonItem... Возможно, потому, что она внесла некоторую двусмысленность в UIAppearance. В любом случае, поскольку мне больше не нужна эта строка, я могу легко ее удалить. Я по-прежнему оставлю свой вопрос открытым, так как считаю такое поведение очень странным, и поэтому в некотором смысле вопрос все еще остается без ответа.

В качестве дополнительной информации - контроллер представления, который столкнулся с этими проблемами, содержал в себе табличное представление.


person Andriy Gordiychuk    schedule 19.01.2017    source источник
comment
Вау у меня точно такая же проблема   -  person Renetik    schedule 08.05.2017


Ответы (5)


Я не могу воспроизвести ни одной проблемы. Здесь вы можете видеть, что мы меняем цвет оттенка кнопки правой панели между красным и зеленым; это делается путем установки tintColor элемента кнопки панели непосредственно в коде:

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

        let c = self.replyButton.tintColor
        if c == UIColor.red {
            self.replyButton.tintColor = .green
        } else {
            self.replyButton.tintColor = .red
        }

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

person matt    schedule 19.01.2017
comment
Спасибо за указание на это! Теперь, когда я знаю, что это не новое поведение, я начал копать глубже и понял, что проблема существует, потому что я устанавливаю определенный визуальный стиль через UIAppearance. Я еще не понял, какой из них вызывает проблему, но как только я это сделаю, я обновлю вопрос. В любом случае я думаю, что это странное поведение, так как установка tintColor вручную должна иметь возможность перезаписывать любые настройки UIAppearance... - person Andriy Gordiychuk; 19.01.2017
comment
Я нашел проблему и обновил свой вопрос. Я все еще на 100% озадачен тем, что, черт возьми, происходит, но все равно большое спасибо за то, что указали мне правильное направление! - person Andriy Gordiychuk; 19.01.2017
comment
Вы также можете найти этот мой ответ каким-то образом актуальным: stackoverflow.com/a/21592073/341994 - person matt; 19.01.2017
comment
Благодарность! Однако я до сих пор не понимаю, как атрибут внешнего вида для ячейки таблицы может конфликтовать с элементом кнопки панели! :) - person Andriy Gordiychuk; 20.01.2017
comment
Я тоже этого не понимаю. Вы можете отправить отчет об ошибке в Apple, если сможете создать простой воспроизводимый случай. - person matt; 20.01.2017
comment
У меня точно такая же проблема, как и у него, сейчас я пытаюсь прокомментировать все модификации внешнего вида tintColor, что сломало это здесь. - person Renetik; 08.05.2017

Я столкнулся с той же проблемой и в итоге решил ее, выполнив следующие шаги:

1) Создайте выход к элементу кнопки панели. Мой назывался «closeButton». 2) Напишите следующий код:

override func viewWillAppear(animated: Bool) {
  let barButtonAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
  closeButton.setTitleTextAttributes(barButtonAttributes, for: .normal)
}

Обязательно поместите код в viewWillAppear, так как это переопределяет настройки UIAppearance по умолчанию.

person Eman Harout    schedule 17.02.2018

Так что в моем случае эта строка

UIActivityIndicatorView.appearance.tintColor = FlatWhite;

установленный в didFinishLaunchingWithOptions, изменил все UIBarItemItems.tintColor на синий по умолчанию, и было невозможно изменить его иначе, чем установив цвет оттенка на родительской панели...

Когда я комментирую эту строку, все работает, когда раскомментирую, она перестает работать. Для меня это явная ошибка в рамках IOS. Это трудно предсказать, потому что в других случаях это немного отличается.

person Renetik    schedule 08.05.2017

Я предполагаю, что вы используете UIImageRenderingMode.alwaysOriginal, и это вызывает проблему.

public enum UIImageRenderingMode : Int {

     case automatic // Use the default rendering mode for the context where the image is used
     case alwaysOriginal // Always draw the original image, without treating it as a template
     case alwaysTemplate // Always draw the image as a template image, ignoring its color information

}

Используйте вместо этого .alwaysTemplate

person Victor Do    schedule 14.11.2017

Если у вас есть контроллер представления, встроенный в контроллер навигации, в контроллере навигации проверьте свойства View/Tint панели навигации. Я обнаружил, что это переопределяет любой код, помещенный в ViewDidLoad для контроллера представления.

person richc    schedule 21.07.2018