Как изменить цвет фона текстового поля в UISearchController?

Как изменить серый фон по умолчанию в текстовом поле поиска UISearchController?

Как изменить цвет фона текстового поля в UISearchController?

увидеть это stackoverflow.com/questions/52905371/…

Wings 13.12.2018 14:12

@wings что происходит, когда Apple решает изменить иерархию представлений?

Rakesha Shastri 13.12.2018 14:13

Пожалуйста, посмотрите этот ответ: stackoverflow.com/questions/52870677/…

Sagar Chauhan 13.12.2018 14:14

@RakeshaShastri ... Я не понимаю: D

Wings 13.12.2018 14:15

@SagarChauhan, что происходит, когда Apple решает сменить ключ?

Rakesha Shastri 13.12.2018 14:16

@RakeshaShastri, он не изменит ключ сейчас, и если есть какие-либо изменения, это не повлияет на живое приложение. В новой версии вы можете изменить этот ключ в соответствии с решением Apple.

Sagar Chauhan 13.12.2018 14:19

@SagarChauhan, да, но они не скажут вам новый ключ. То, что вы знаете это сейчас, не означает, что вы узнаете новый. Кроме того, если Apple меняет ключ, это будет влияет на живое приложение. Вы не можете кодировать ОС, которая еще не была выпущена.

Rakesha Shastri 13.12.2018 14:20

@RakeshaShastri, Ооо, Предположим, старое приложение имеет функцию flatMap, и теперь оно работает. Итак, Apple обновила название функции как compactMap, поэтому она работает в реальном приложении. Правильно ?

Sagar Chauhan 13.12.2018 14:23

@SagarChauhan Wat ?! нет, это не так. почему это повлияет на живые приложения ?! Либо вы неправильно объясняете свою точку зрения (что может случиться, ничего страшного), либо вы сильно ошибаетесь в том, как все это работает (что было бы довольно большим делом) ...

Eric Aya 13.12.2018 15:40

поделиться исходным кодом SearchController

Kathiresan Murugan 20.12.2018 06:01
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
7
10
10 372
11
Перейти к ответу Данный вопрос помечен как решенный

Ответы 11

Вы пробовали что-то вроде

searchController.searchBar.backgroundColor = UIColor.blue

Хорошо! Может быть, вы можете попробовать с subviews внутри searchBar, и если вы найдете subview, который является UITextField, измените его backgroundColor

Francesco Destino 13.12.2018 16:54
Ответ принят как подходящий

Вот пример того, как установить фон textField.

class ViewController: UIViewController {

    let searchController = UISearchController(searchResultsController: nil)

    private lazy var searchTextField: UITextField? = { [unowned self] in
        var textField: UITextField?
        self.searchController.searchBar.subviews.forEach({ view in
            view.subviews.forEach({ view in
                if let view  = view as? UITextField {
                    textField = view
                }
            })
        })
        return textField
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        searchController.obscuresBackgroundDuringPresentation = false
        searchController.searchBar.placeholder = "Search Candies"
        navigationItem.searchController = searchController
        definesPresentationContext = true

        if let bg = self.searchTextField?.subviews.first {
            bg.backgroundColor = .green
            bg.layer.cornerRadius = 10
            bg.clipsToBounds = true
        }
    }
}

Результат

Не лучший способ найти UITextField. Сделайте это хотя бы рекурсивным. :(

Timur Bernikovich 18.12.2018 11:17

Чтобы обновить фон UISearchController, нужно изменить фоновое изображение.

Если вы видите UISearchController в визуальном отладчике, вы можете узнать, что его фоном является UIImageView:

Итак, вы должны сделать маленькое изображение своей панели поиска и установить его на seachBar следующим образом:

    lazy var searchController: UISearchController = {

        let searchController = UISearchController(searchResultsController: nil)

        searchController.searchBar.placeholder = "Search"
        searchController.searchBar.tintColor = UIColor.black
        searchController.searchBar.searchBarStyle = .minimal
        // Set background image to searchBar so it will resize
        searchController.searchBar.setSearchFieldBackgroundImage(UIImage(named: "oval_static"), for: .normal)

        definesPresentationContext = true

        return searchController
    }()

Изображение searchBar (в проекте я рекомендую использовать формат изображения .pdf или .png, здесь только скриншот):

UISearchBar изменит его размер по мере необходимости, и результат будет:

Более того, мы можем сделать что-то вроде этого, чтобы создать собственный фон только в коде:

/// Just random extension to make image from UIView, you can use your own
extension UIView {

func asImage() -> UIImage {
    let renderer = UIGraphicsImageRenderer(bounds: bounds)
    return renderer.image { rendererContext in
        layer.render(in: rendererContext.cgContext)
    }
}}

lazy var searchController: UISearchController = {

        let searchController = UISearchController(searchResultsController: nil)

        searchController.searchBar.placeholder = "Search"
        searchController.searchBar.tintColor = UIColor.black
        searchController.searchBar.searchBarStyle = .minimal

        // Create own view with custom properties
        // Default height is 36 points
        let differentColorSearchBar = UIView(frame: CGRect(x: 0, y: 0, width: 10, height: 36))

        differentColorSearchBar.layer.cornerRadius = 8
        differentColorSearchBar.clipsToBounds = true
        differentColorSearchBar.backgroundColor = UIColor.blue

        searchController.searchBar.setSearchFieldBackgroundImage(differentColorSearchBar.asImage(), for: .normal)

        definesPresentationContext = true

        return searchController
    }

Результат (конечно, вы можете изменить другие свойства searchBar, чтобы сделать его лучше, но я просто покажу вам, как правильно изменить фон):

Я рекомендую избегать частных свойств, просто используйте open! Надеюсь, это поможет.

Я делаю это так, код Objective-C:

UITextField *searchField = [_navigationSearchBar valueForKey:@"searchField"];
searchField.backgroundColor = [UIColor defaultSeacrhBarColor];
searchField.textColor = [UIColor defaultWhiteColor];
searchField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:searchTitle];
UILabel *placeholderLabel = [searchField valueForKey:@"placeholderLabel"];
placeholderLabel.textColor = [UIColor lightTextColor];

UIButton *clearButton = [searchField valueForKey:@"clearButton"];
[clearButton setImage:[clearButton.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] forState:UIControlStateNormal];
clearButton.tintColor = [UIColor defaultWhiteColor];

_navigationSearchBar.delegate = self;
[_navigationSearchBar setTranslucent:NO];
[_navigationSearchBar setBackgroundImage:nil];
[_navigationSearchBar setBarTintColor:[UIColor defaultNavigationBarColor]];
[_navigationSearchBar setBackgroundColor:[UIColor defaultNavigationBarColor]];
[_navigationSearchBar setImage:[UIImage imageNamed:@"Search_Icon"] forSearchBarIcon:UISearchBarIconSearch state:UIControlStateNormal];
_navigationSearchBar.clipsToBounds = YES;
[_navigationBar addSubview:_navigationSearchBar];

У Apple есть ключ searchField для обнаружения текстового поля в searchBar. Итак, сначала безопасно получите это текстовое поле и сделайте все, что хотите, с помощью текстового поля.

let searchController = UISearchController(searchResultsController: nil)
searchController.searchResultsUpdater = self
searchController.searchBar.placeholder = "Search here..."
searchController.searchBar.delegate = self
searchController.searchBar.tintColor = .white
searchController.searchBar.barTintColor = .white
searchController.hidesNavigationBarDuringPresentation = false
searchController.obscuresBackgroundDuringPresentation = false

if let textfield = searchController.searchBar.value(forKey: "searchField") as? UITextField {

    // Set text colour of text field   
    textfield.textColor = UIColor.blue

    if let backgroundview = textfield.subviews.first {

        // Get background view and change background color
        backgroundview.backgroundColor = UIColor.white

        // Set rounded corner
        backgroundview.layer.cornerRadius = 10
        backgroundview.clipsToBounds = true
    }
}

if #available(iOS 11.0, *) {
    self.navigationItem.searchController = searchController
} else {
    self.tblCustomers.tableHeaderView = searchController.searchBar
}

Это рабочий код, который я реализовал в своем текущем проекте. Тем не менее, если у вас есть какие-либо вопросы, дайте мне знать.

Я надеюсь, что это поможет вам.

Когда вы пишете .value(forKey: "searchField"), вы звоните в Apple, чтобы отклонить ваше приложение в любое время, когда они это заметят. Кроме того, ваше приложение выйдет из строя, если они просто переименуют атрибут searchField в любой новой версии.

Kamran 20.12.2018 06:12

@Kamran, Во-первых, у меня есть безопасное получение textField путем необязательного развертывания if let, так что это не приведет к сбою приложения. Во-вторых, если приложение работает, то как оно вылетит. Кроме того, одно из моих приложений уже работает, где доступен этот код.

Mayur Karmur 20.12.2018 06:21

Да, дополнительная распаковка будет работать, если .value(forKey: "searchField") не выйдет из строя. Если внутри этого метода произошел сбой, дополнительная распаковка не спасет. Если приложение работает и они переименовали атрибут в новой операционной системе, оно начнет вылетать, так как этот ключ будет недоступен. Наконец, ваше приложение и многие другие приложения работают, потому что Apple не заметила, что вы обращаетесь к API private. Заметив это, они могут отклонить приложение.

Kamran 20.12.2018 06:27

Макс используйте эту функцию ниже для изменения цвета.

extension UISearchBar {
  func setBackgroundColor(){
    if let view:UIView = self.subviews.first {
        for curr in view.subviews {
            guard let searchBarBackgroundClass = NSClassFromString("UISearchBarBackground") else {
                return
            }
            if curr.isKind(of:searchBarBackgroundClass){
                if let imageView = curr as? UIImageView{
                    imageView.backgroundColor = .red
                    break
                }
            }
        }
    }
  }
}

Используйте эту функцию с панель поиска.

searchBarController.searchBar.setBackgroundColor()

Нет никакого надлежащего / общедоступного способа изменить цвет фона этой панели поиска. Есть несколько способов использования частного API, например answer @sanjayshah, но в этом случае есть вероятность, что Apple отклонит ваше приложение. Я думаю, вам следует перейти к использованию цвета фона по умолчанию. Большинство приложений используют то же самое.

Рекурсивная версия ответа @Kamran с лучшим лучшим случаем и средним временем работы. Принятая версия у меня не работает на iOS 13+.

private lazy var searchTextField: UITextField? = { [unowned self] in
    guard let searchBar = self.searchController?.searchBar else { return nil }
    var views =  searchBar.subviews
    while !views.isEmpty {
        guard let view = views.popLast() else { break }
        if let textfield = view as? UITextField {
            return textfield
        }
        views += view.subviews
    }
    return nil
}()

В iOS13 и более поздних версиях searchTextField является членом UISearchBar. Итак, вы можете использовать что-то вроде этого:

searchController.searchBar.searchTextField.backgroundColor = UIColor.blue

Будьте осторожны, у Apple нет надлежащей записи в SDK, показывающей, что это свойство появилось в iOS 13, поэтому, если вы поддерживаете iOS 12 или более раннюю версию, оно не показывает вам никаких предупреждений. Обязательно заверните его только для iOS 13.

Сначала проверьте платформу,

чем вносить изменения, потому что iOS 13 не принимает много трюков, сделанных для iOS 12

if #available(iOS 13, *) {
   searchController.searchBar.searchTextField.backgroundColor = .white 
} else {

for textField in searchController.searchBar.subviews.first.subviews where   textField is UITextField {
textField.subviews.first.backgroundColor = .white
textField.subviews.first.layer.cornerRadius = 10
textField.subviews.first.layer.masksToBounds = true
  }
}

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

if #available(iOS 13.0, *)
    {
        searchBar.searchTextField.textColor       = .black
        searchBar.searchTextField.backgroundColor = .red
    }
    else if let textFieldInsideSearchBar = searchBar.value(forKey: "searchField") as? UITextField
    {
        textFieldInsideSearchBar.textColor = .black
        let backgroundView = UIView(frame: textFieldInsideSearchBar.bounds)
        backgroundView.backgroundColor = .red
        backgroundView.layer.cornerRadius = 10
        backgroundView.clipsToBounds = true
        textFieldInsideSearchBar.insertSubview(backgroundView, at: 1)
    }

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