How to change UISearchBar Placeholder and image tint color?

前端 未结 12 2329
暖寄归人
暖寄归人 2020-11-29 01:24

I\'ve been trying search results for hours, but I can\'t get this figured out. Perhaps it isn\'t possible. I\'m trying to change the tint color of the placeholder text and m

相关标签:
12条回答
  • 2020-11-29 02:15

    If you have a custom image you could use, you can set the image and change the placeholder text color using something similar to the following:

    [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}]];
    }
    

    In that example I used purpleColor, instead you can use the + (UIColor *)colorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha method to create your custom dark green color.

    EDIT: I just realized you were writing it in swift... duh. Quickly typed this out so I didn't leave the answer in just 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)
        }
    
    0 讨论(0)
  • 2020-11-29 02:17
    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
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-29 02:18

    Just found this thread, sorry about the bump given the age. However it helped me in trying to fix my issue, and adding onto @m_katsifarakis answer, I added more to his existing category.

    Adding additional color + font support for both placeholder and input text.

    Only tested on iOS 13 as that's all I am supporting.

    @interface UISearchBar (ColorandFont)
    - (void)setPlaceholderColor:(UIColor *)placeholderColor setPlaceholderFont:(UIFont *)placeholderFont;
    - (void)setTextColor:(UIColor *)textColor setTextFont:(UIFont *)textFont;
    @end
    @implementation UISearchBar (ColorandFont)
    
    //Placeholder Color
    - (void)setPlaceholderColor:(UIColor *)placeholderColor setPlaceholderFont:(UIFont *)placeholderFont{
        UILabel *labelView = [self placeholderText:self];
        [labelView setTextColor:placeholderColor];
        [labelView setFont:placeholderFont];
    }
    - (UILabel *)placeholderText:(UIView *)view {
        for (UIView *v in [view subviews]) {
            if ([v isKindOfClass:[UILabel class]]) {
                return (UILabel *)v;
            }
    
            UIView *labelView = [self placeholderText:v];
            if (labelView) {
                return (UILabel *)labelView;
            }
        }
        return nil;
    }
    
    //Text Color
    - (void)setTextColor:(UIColor *)textColor setTextFont:(UIFont *)textFont{
        UITextField *textView = [self searchBarText:self];
        [textView setTextColor:textColor];
        [textView setFont:textFont];
    }
    - (UITextField *)searchBarText:(UIView *)view {
        for (UIView *v in [view subviews]) {
            if ([v isKindOfClass:[UITextField class]]) {
                return (UITextField *)v;
            }
    
            UIView *textView = [self searchBarText:v];
            if (textView) {
                return (UITextField *)textView;
            }
        }
        return nil;
    }
    @end
    

    Usage (I used in viewDidLoad and Appear) given my current setup, results may vary:

    [self.searchBar setPlaceholderColor:[UIColor lightTextColor] setPlaceholderFont:[UIFont italicSystemFontOfSize:13]];
    [self.searchBar setTextColor:[UIColor whiteColor] setTextFont:[UIFont systemFontOfSize:16]];
    
    0 讨论(0)
  • 2020-11-29 02:19

    Details

    • Xcode Version 11.0 (11A420a), iOS 13, swift 5

    Solution

    import UIKit
    
    extension UISearchBar {
    
        func getTextField() -> UITextField? { return value(forKey: "searchField") as? UITextField }
        func set(textColor: UIColor) { if let textField = getTextField() { textField.textColor = textColor } }
        func setPlaceholder(textColor: UIColor) { getTextField()?.setPlaceholder(textColor: textColor) }
        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
            @unknown default: break
            }
        }
    
        func setSearchImage(color: UIColor) {
            guard let imageView = getTextField()?.leftView as? UIImageView else { return }
            imageView.tintColor = color
            imageView.image = imageView.image?.withRenderingMode(.alwaysTemplate)
        }
    }
    
    private extension UITextField {
    
        private class Label: UILabel {
            private var _textColor = UIColor.lightGray
            override var textColor: UIColor! {
                set { super.textColor = _textColor }
                get { return _textColor }
            }
    
            init(label: UILabel, textColor: UIColor = .lightGray) {
                _textColor = textColor
                super.init(frame: label.frame)
                self.text = label.text
                self.font = label.font
            }
    
            required init?(coder: NSCoder) { super.init(coder: coder) }
        }
    
    
        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)
            }
        }
    
        var placeholderLabel: UILabel? { return value(forKey: "placeholderLabel") as? UILabel }
    
        func setPlaceholder(textColor: UIColor) {
            guard let placeholderLabel = placeholderLabel else { return }
            let label = Label(label: placeholderLabel, textColor: textColor)
            setValue(label, forKey: "placeholderLabel")
        }
    
        func getClearButton() -> UIButton? { return value(forKey: "clearButton") as? UIButton }
    }
    

    Full Sample

    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 = .default
            view.addSubview(searchBar)
    
            searchBar.placeholder = "placeholder"
            searchBar.set(textColor: .brown)
            searchBar.setTextField(color: UIColor.green.withAlphaComponent(0.3))
            searchBar.setPlaceholder(textColor: .white)
            searchBar.setSearchImage(color: .white)
            searchBar.setClearButton(color: .red)
        }
    }
    

    Result

    0 讨论(0)
  • 2020-11-29 02:19

    Swift 3: If you want to change the placeholder, clearbutton and magnifier glass

        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
    
    0 讨论(0)
  • 2020-11-29 02:24

    I found a way to change the textfiled in search bar. It works in swift 3 and Xcode8.

    Firstly, subclass the UISearchBar class.

    class CustomSearchBar: UISearchBar {
    

    UISearchBar include a view which has the important textfield you wanted. Following function get the index in subviews.

    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)
    }
    

    There you go, enjoy for this.

    0 讨论(0)
提交回复
热议问题