it-swarm.com.ru

Как изменить UISearchBar Placeholder и цвет оттенка изображения?

Я искал результаты поиска в течение нескольких часов, но не могу понять это. Возможно, это невозможно. Я пытаюсь изменить цвет оттенка текста заполнителя и увеличительного стекла UISearchBar. Я ориентируюсь только на iOS 8.0+, если это имеет значение. Вот мой код и как он выглядит сейчас:

let searchBar = UISearchBar()
searchBar.placeholder = "Search"
searchBar.searchBarStyle = UISearchBarStyle.Minimal
searchBar.tintColor = UIColor.whiteColor()

a busy cat

Я бы хотел, чтобы поисковое и увеличительное стекло было белым или, возможно, темно-зеленым. 

21
Kyle Bashour

Если у вас есть пользовательское изображение, которое вы можете использовать, вы можете установить изображение и изменить цвет текста заполнителя, используя нечто похожее на следующее:

[searchBar setImage:[UIImage imageNamed:@"SearchWhite"] forSearchBarIcon:UISearchBarIconSearch state:UIControlStateNormal];

UITextField *searchTextField = [searchBar valueForKey:@"_searchField"];    
if ([searchTextField respondsToSelector:@selector(setAttributedPlaceholder:)]) {
    UIColor *color = [UIColor purpleColor];
    [searchTextField setAttributedPlaceholder:[[NSAttributedString alloc] initWithString:@"Search" attributes:@{NSForegroundColorAttributeName: color}]];
}

В этом примере я использовал purpleColor, вместо этого вы можете использовать метод + (UIColor *)colorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha для создания собственного темно-зеленого цвета.

Правка: Я только что понял, что вы пишете это на Swift ... да. Быстро напечатал это, чтобы я не оставил ответ только в Obj-C.

    searchBar.setImage(UIImage(named: "SearchWhite"), forSearchBarIcon: UISearchBarIcon.Search, state: UIControlState.Normal);

    var searchTextField: UITextField? = searchBar.valueForKey("searchField") as? UITextField
    if searchTextField!.respondsToSelector(Selector("attributedPlaceholder")) {
        var color = UIColor.purpleColor()
        let attributeDict = [NSForegroundColorAttributeName: UIColor.purpleColor()]
        searchTextField!.attributedPlaceholder = NSAttributedString(string: "search", attributes: attributeDict)
    }

Swift 3.0

    var searchTextField: UITextField? = searchBar.value(forKey: "searchField") as? UITextField
    if searchTextField!.responds(to: #selector(getter: UITextField.attributedPlaceholder)) {
        let attributeDict = [NSForegroundColorAttributeName: UIColor.white]
        searchTextField!.attributedPlaceholder = NSAttributedString(string: "Search", attributes: attributeDict)
    }
30
c_rath

Подробности

  • Версия Xcode 10.1 (10B61)
  • Swift 4.2

Решение

import UIKit

extension UISearchBar {

    func getTextField() -> UITextField? { return value(forKey: "searchField") as? UITextField }
    func setText(color: UIColor) { if let textField = getTextField() { textField.textColor = color } }
    func setPlaceholderText(color: UIColor) { getTextField()?.setPlaceholderText(color: color) }
    func setClearButton(color: UIColor) { getTextField()?.setClearButton(color: color) }

    func setTextField(color: UIColor) {
        guard let textField = getTextField() else { return }
        switch searchBarStyle {
        case .minimal:
            textField.layer.backgroundColor = color.cgColor
            textField.layer.cornerRadius = 6
        case .prominent, .default: textField.backgroundColor = color
        }
    }

    func setSearchImage(color: UIColor) {
        guard let imageView = getTextField()?.leftView as? UIImageView else { return }
        imageView.tintColor = color
        imageView.image = imageView.image?.withRenderingMode(.alwaysTemplate)
    }
}

extension UITextField {

    private class ClearButtonImage {
        static private var _image: UIImage?
        static private var semaphore = DispatchSemaphore(value: 1)
        static func getImage(closure: @escaping (UIImage?)->()) {
            DispatchQueue.global(qos: .userInteractive).async {
                semaphore.wait()
                DispatchQueue.main.async {
                    if let image = _image { closure(image); semaphore.signal(); return }
                    guard let window = UIApplication.shared.windows.first else { semaphore.signal(); return }
                    let searchBar = UISearchBar(frame: CGRect(x: 0, y: -200, width: UIScreen.main.bounds.width, height: 44))
                    window.rootViewController?.view.addSubview(searchBar)
                    searchBar.text = "txt"
                    searchBar.layoutIfNeeded()
                    _image = searchBar.getTextField()?.getClearButton()?.image(for: .normal)
                    closure(_image)
                    searchBar.removeFromSuperview()
                    semaphore.signal()
                }
            }
        }
    }

    func setClearButton(color: UIColor) {
        ClearButtonImage.getImage { [weak self] image in
            guard   let image = image,
                let button = self?.getClearButton() else { return }
            button.imageView?.tintColor = color
            button.setImage(image.withRenderingMode(.alwaysTemplate), for: .normal)
        }
    }

    func setPlaceholderText(color: UIColor) {
        attributedPlaceholder = NSAttributedString(string: placeholder != nil ? placeholder! : "", attributes: [.foregroundColor: color])
    }

    func getClearButton() -> UIButton? { return value(forKey: "clearButton") as? UIButton }
}

Полный образец

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let searchBar = UISearchBar(frame: CGRect(x: 0, y: 20, width: UIScreen.main.bounds.width, height: 44))
        searchBar.searchBarStyle = .minimal
        view.addSubview(searchBar)

        searchBar.placeholder = "placeholder"
        searchBar.setText(color: .brown)
        searchBar.setTextField(color: UIColor.green.withAlphaComponent(0.3))
        searchBar.setPlaceholderText(color: .white)
        searchBar.setSearchImage(color: .white)
        searchBar.setClearButton(color: .red)
    }
}

Результат

enter image description here enter image description here

62
Vasily Bodnarchuk

Swift 3: если вы хотите заменить заполнитель, кнопку очистки и стекло лупы

    let textFieldInsideSearchBar = searchBar.value(forKey: "searchField") as? UITextField
    textFieldInsideSearchBar?.textColor = UIColor.white

    let textFieldInsideSearchBarLabel = textFieldInsideSearchBar!.value(forKey: "placeholderLabel") as? UILabel
    textFieldInsideSearchBarLabel?.textColor = UIColor.white

    let clearButton = textFieldInsideSearchBar?.value(forKey: "clearButton") as! UIButton
    clearButton.setImage(clearButton.imageView?.image?.withRenderingMode(.alwaysTemplate), for: .normal)
    clearButton.tintColor = UIColor.white

    let glassIconView = textFieldInsideSearchBar?.leftView as? UIImageView

    glassIconView?.image = glassIconView?.image?.withRenderingMode(.alwaysTemplate)
    glassIconView?.tintColor = UIColor.white
9
phitsch

Вы можете изменить цвет текста, не нарушая правила частного API:

UILabel.appearanceWhenContainedInInstancesOfClasses([UITextField.self]).textColor = UIColor.whiteColor()
4
netshark1000

Небольшое обновление к великому ответу Василия Боднарчука.

Свифт 4+

NSForegroundColorAttributeName был изменен на NSAttributedStringKey.foregroundColor

1
Mike Carpenter
extension UISearchBar {
    var textField: UITextField? { return value(forKey: "searchField") as? UITextField }
    var placeholderLabel: UILabel? { return textField?.value(forKey: "placeholderLabel") as? UILabel }
    var icon: UIImageView? { return textField?.leftView as? UIImageView }
    var iconColor: UIColor? {
        get {
            return icon?.tintColor
        }
        set {
            icon?.image = icon?.image?.withRenderingMode(.alwaysTemplate)
            icon?.tintColor = newValue
        }
    }
}
1
Geva

Я сделал расширение панели поиска Swift 4.1:

import Foundation
import UIKit
extension UISearchBar{
    func setTextField(placeHolderColor:UIColor = .gray,placeHolder:String = "Search Something",textColor:UIColor = .white,backgroundColor:UIColor = .black,
                      placeHolderFont:UIFont = UIFont.systemFont(ofSize: 12.0),
                      textFont:UIFont =  UIFont.systemFont(ofSize: 12.0) ){
        for item in self.subviews{
            for mainView in (item as UIView).subviews{
                mainView.backgroundColor = backgroundColor
                if mainView is UITextField{
                    let textField = mainView as? UITextField
                    if let _textF = textField{
                        _textF.text = "success"
                        _textF.textColor = textColor
                        _textF.font      = textFont
                        _textF.attributedPlaceholder = NSMutableAttributedString.init(string: placeHolder, attributes: [NSAttributedStringKey.foregroundColor : placeHolderColor,
                                                                                                                               NSAttributedStringKey.font : placeHolderFont])
                    }
                }
            }
        }
    }
}

Вы можете использовать это для своего searchBar как это:

controller.searchBar.setTextField(placeHolderColor: .white,
 placeHolder: "Search A Pet",
 textColor: .white,
 backgroundColor: .green,
 placeHolderFont: UIFont.systemFont(ofSize: 14.0),
 textFont: UIFont.systemFont(ofSize: 14.0))
1
Abhimanyu Rathore

Я нашел способ изменить текстовый файл в строке поиска .... Он работает в Swift 3 и Xcode8.

Во-первых, создайте подкласс класса UISearchBar.

class CustomSearchBar: UISearchBar {

UISearchBar включает представление, которое имеет важное текстовое поле, которое вы хотели. Следующая функция получить индекс в подпредставлениях.

func indexOfSearchFieldInSubviews() -> Int! {
    var index: Int!
    let searchBarView = subviews[0]
    for (i, subview) in searchBarView.subviews.enumerated() {
        if subview.isKind(of: UITextField.self) {
            index = i
            break
        }
    }
    return index
}


override func draw(_ rect: CGRect) {
    // Find the index of the search field in the search bar subviews.
    if let index = indexOfSearchFieldInSubviews() {
        // Access the search field
        let searchField: UITextField = subviews[0].subviews[index] as! UITextField
        // Set its frame.
        searchField.frame = CGRect(x: 5, y: 5, width: frame.size.width - 10, height: frame.size.height - 10)
        // Set the font and text color of the search field.
        searchField.font = preferredFont
        searchField.textColor = preferredTextColor

        // Set the placeholder and its color
        let attributesDictionary = [NSForegroundColorAttributeName: preferredPlaceholderColor.cgColor]
        searchField.attributedPlaceholder = NSAttributedString(string: preferredPlaceholder, attributes: attributesDictionary)

        // Set the background color of the search field.
        searchField.backgroundColor = barTintColor
    }

    super.draw(rect)
}

Вот, пожалуйста, наслаждайтесь этим.

1
Jerome

Для тех, кто просто пытается изменить текст и испытывает затруднения при просмотре обновленного заполнителя, он работал для меня, поместив его здесь вместо viewDidLoad.

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    self.searchBar.placeholder = @"My Custom Text";
}
0
skensell

Я не мог заставить это работать должным образом с любым из вышеупомянутых решений. 

Я создал следующую категорию UISearchBar, которая правильно работает в iOS 8.4 и 10.3:

UISearchBar + PlaceholderColor.h

#import <UIKit/UIKit.h>

@interface UISearchBar (PlaceholderColor)

- (void)setPlaceholderColor:(UIColor *)placeholderColor;

@end

UISearchBar + PlaceholderColor.m

#import "UISearchBar+PlaceholderColor.h"

@implementation UISearchBar (PlaceholderColor)

- (void)setPlaceholderColor:(UIColor *)placeholderColor {
    UILabel *labelView = [self searchBarTextFieldLabelFromView:self];
    [labelView setTextColor:placeholderColor];
}

- (UILabel *)searchBarTextFieldLabelFromView:(UIView *)view {
    for (UIView *v in [view subviews]) {
        if ([v isKindOfClass:[UILabel class]]) {
            return (UILabel *)v;
        }

        UIView *labelView = [self searchBarTextFieldLabelFromView:v];
        if (labelView) {
            return (UILabel *)labelView;
        }
    }

    return nil;
}

@end

ИСПОЛЬЗОВАНИЕ:

[mySearchBar setPlaceholderColor:[UIColor redColor]];

ВАЖНАЯ ЗАМЕТКА:

Убедитесь, что вы вызываете setPlaceholderColor: ПОСЛЕ, ваш UISearchBar был добавлен в представление и создал его иерархию представления.

Если вы открываете панель поиска программным способом, назовите ее ПОСЛЕ вашего вызова становления становленияFirstResponder, как такового:

[mySearchBar becomeFirstResponder];
[searchBar setPlaceholderColor:[UIColor redColor]];

В противном случае, если вы используете UISearchBarDelegate:

- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
    [searchBar setPlaceholderColor:[UIColor redColor]];
}
0
m_katsifarakis