UISearchBar отменить цвет кнопки?
Когда я помещаю UISearchBar в представление в Интерфейсном Разработчике и меняю его стиль на Черный Непрозрачный, кнопка отмены остается не совсем подходящей сине-серой и не становится черной.
Как сделать кнопку отмены черной?
РЕДАКТИРОВАТЬ: Это работает так:
// Assume a UISearchBar searchBar.
NSArray *subviews = [searchBar subviews];
// The index depends on how you configure the searchBar.
UIButton *cancelButton = [subviews objectAtIndex:3];
// Set the style to "normal" style.
[cancelButton setStyle:0];
Но setStyle:
Метод из частной структуры, поэтому это может быть проблемой при отправке приложения в Apple.
10 ответов
Я использовал что-то вроде этого и работал со мной:
[[UIBarButtonItem appearanceWhenContainedIn: [UISearchBar class], nil] setTintColor:[UIColor blackColor]];
он изменил цвет кнопки отмены на черный.
Обновление для iOS 9.0, метод appearanceWhenContainedIn
устарела, использовать appearanceWhenContainedInInstancesOfClasses
вместо:
[[UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:@[[UISearchBar class]]] setTintColor:[UIColor blackColor]];
И в Свифте 3:
UIBarButtonItem.appearance(whenContainedInInstancesOf:[UISearchBar.self]).tintColor = UIColor.black
Проблема с вашим решением состоит в том, что код предполагает, что objectAtIndex:3 является кнопкой отмены. Это не только генерирует предупреждение компилятора, но также, если вы отображаете кнопку "Отмена" программно (например, используя [searchBar setShowsCancelButton:YES]
, вы рискуете сбой приложения.
Более простое решение - установить стиль всей панели поиска в ViewDidLoad(), используя:
searchBar.tintColor = [UIColor colorWithWhite:0.3 alpha:1.0];
это переопределяет стиль, установленный в Интерфейсном Разработчике, НО также меняет цвет кнопки "Отмена" на тот же цвет, что и вся панель (хотя, к сожалению, не позволяет независимо устанавливать стиль кнопки "Отмена").
Попробуйте это и посмотрите: (Я тестировал код ниже со Swift 4.1 - Xcode 9.3-beta4)
@IBOutlet weak var sbSearchBar: UISearchBar!
sbSearchBar.tintColor = UIColor.red
sbSearchBar.showsCancelButton = true
sbSearchBar.barTintColor = UIColor.blue
sbSearchBar.tintColor = UIColor.red
if let buttonItem = sbSearchBar.subviews.first?.subviews.last as? UIButton {
buttonItem.setTitleColor(UIColor.yellow, for: .normal)
}
Для iOS 10:
UISearchBar.appearance().tintColor = UIColor.red //cancel button color
UISearchBar.appearance().barTintColor = UIColor.blue //background button color
В Swift 4.2
let appearance = UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self])
appearance.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor(named: "goldColor")!], for: .normal)
Это работает для меня. Спасибо @Tim Semple
Это обновленная версия ответа Хоссама Гариба выше для Swift 3:
UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self] ).tintColor = UIColor.red
Но это не отменит внешний вид, если он уже был установлен в другом месте для UIBarButtonItem.
Например, в моем контроллере navbar мне пришлось изменить это:
UIBarButtonItem.appearance().setTitleTextAttributes([NSForegroundColorAttributeName:UIColor.white], for: UIControlState.normal)
Для этого для решения выше, чтобы работать:
UIBarButtonItem.appearance(whenContainedInInstancesOf: [UINavigationBar.self] ).setTitleTextAttributes([NSForegroundColorAttributeName:UIColor.white], for: UIControlState.normal)
Придумал следующее решение, которое также работает с iOS 13.0 и iOS 12.4, должно работать и над предыдущими версиями до iOS 9.0. Следующее решение предназначено для:
- Цвет кнопки отмены (нормальное состояние).
- Цвет кнопки отмены (отключенное состояние).
- Цвет фона текстового поля панели поиска (нормальное состояние).
Для цели C:
[[UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:@[[UISearchBar class]]] setTintColor:[UIColor whiteColor]];
[[UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:@[[UISearchBar class]]] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor whiteColor]} forState:UIControlStateNormal];
[[UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:@[[UISearchBar class]]] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor whiteColor]} forState:UIControlStateDisabled];
[[UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:@[[UISearchBar class]]] setTitleTextAttributes:@{NSBackgroundColorAttributeName: [UIColor whiteColor]} forState:UIControlStateNormal];
Приведенный выше код также фиксированный мои проблемы пользовательского интерфейса для прошивки 13 и iPhone X. Я включил этот код в моем AppDelegate.m классе в didFinishLaunchingWithOptions функции, так что изменения можно были бы сделать в целом приложение.
let view: UIView = self.searchBar.subviews[0] as UIView
let subViewsArray = view.subviews
for subView: UIView in subViewsArray {
if let cancelButt = subView as? UIButton{
cancelButt.setTitleColor(UIColor.white, for: .normal)
}
}
Это сработало для меня
Нажмите на строку поиска и установите цвет оттенка под представлением из Интерфейсного Разработчика.
Я взял ответ Бенджамина и соединил его с безопасным Array
поиск для создания короткой, но безопасной функциональной версии:
searchController.searchBar.tintColor = UIColor.whiteColor()
(searchController.searchBar.subviews[safe: 0]?.subviews as? [UIView])?
.filter({$0.isKindOfClass(UITextField)})
.map({$0.tintColor = .lightGrayColor()})
Это приводит к окрашиванию кнопки Отмена в белый цвет и курсора при наборе серого. В противном случае он будет белым и, следовательно, не виден. searchController
является объектом типа UISearchController
, Если кто-то хочет использовать его в контроллере результатов, замените его на self
,
Реализация safe:
подстрочный ответ нкукушкина:
extension Array {
subscript(safe index: Int) -> T? {
return indices(self) ~= index ? self[index] : nil
}
}
Для тех, кто хочет воспроизвести такое же поведение в Swift:
override func viewWillAppear(animated: Bool) {
self.searchBar.tintColor = UIColor.whiteColor()
let view: UIView = self.searchBar.subviews[0] as! UIView
let subViewsArray = view.subviews
for (subView: UIView) in subViewsArray as! [UIView] {
println(subView)
if subView.isKindOfClass(UITextField){
subView.tintColor = UIColor.blueColor()
}
}
}