我可以更改颜色/图像UISearchBar清除按钮吗?

时间:2018-05-17 05:10:21

标签: ios swift4 uisearchbar

enter image description here

我想将清除按钮颜色更改为白色。我尝试了很多方法,但没有运气。:(我也参考了以下link。但它对我不起作用。

请在下面找到我尝试过的代码。我正在研究最新的ios 11.感谢任何帮助。

class SearchBar: UISearchBar {

    override init(frame: CGRect) {
        super.init(frame: frame)

        sharedInit()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        sharedInit()
    }

    override func awakeFromNib() {
        super.awakeFromNib()
        sharedInit()
    }

    private func sharedInit() {
        self.placeholder = "Search"
        self.setTextColor(color: .white)
        self.setTextFieldColor(color: UIColor.hexString("549C64"))
        self.setPlaceholderTextColor(color: .white)
        self.setSearchImageColor(color: .white)
        self.setTextFieldClearButtonColor(color: .white)

        if let textfield = self.value(forKey: "searchField") as? UITextField {
            if let backgroundview = textfield.subviews.first {
                backgroundview.layer.cornerRadius = 18.0;
                backgroundview.clipsToBounds = true;
            }
            //textfield.frame = CGRect(x: self.frame.origin.x, y: self.frame.origin.y, width: self.frame.size.width, height: 10.0)
        }


        //NO LUCK FOR HEIGHT
        for subView in self.subviews  {
            for subsubView in subView.subviews  {
                if let textField = subsubView as? UITextField {
                    for subsubView in textField.subviews  {
                        if let btn = subsubView as? UIButton {
                            print(btn)
                        }
                    }

                }else  if let btn = subsubView as? UIButton {
                    print(btn)
                }
            }
            if let btn = subView as? UIButton {
                print(btn)
            }
        }

    }
}

extension UISearchBar {

    private func getViewElement<T>(type: T.Type) -> T? {
        let svs = subviews.flatMap { $0.subviews }
        guard let element = (svs.filter { $0 is T }).first as? T else { return nil }
        return element
    }

    func getSearchBarTextField() -> UITextField? {
        return getViewElement(type: UITextField.self)
    }

    func getSearchBarButton() -> UIButton? {
        return getViewElement(type: UIButton.self)
    }

    func setTextColor(color: UIColor) {
        if let textField = getSearchBarTextField() {
            textField.textColor = color
        }
    }

    func setTextFieldColor(color: UIColor) {
        if let textField = getViewElement(type: UITextField.self) {
            switch searchBarStyle {
            case .minimal:
                textField.layer.backgroundColor = color.cgColor
                textField.layer.cornerRadius = 18.0
                if let backgroundview = textField.subviews.first {
                    backgroundview.layer.cornerRadius = 18.0;
                    backgroundview.clipsToBounds = true;
                }
            case .prominent, .default:
                textField.backgroundColor = color
            }
        }
    }

    func setPlaceholderTextColor(color: UIColor) {
        if let textField = getSearchBarTextField() {
            textField.attributedPlaceholder = NSAttributedString(string: self.placeholder != nil ? self.placeholder! : "", attributes: [NSAttributedStringKey.foregroundColor: color])
        }
    }

    func setTextFieldClearButtonColor(color: UIColor) {
        if let textField = getSearchBarTextField() {
            let button = textField.value(forKey: "_clearButton") as! UIButton
            if let image = button.imageView?.image {
                button.setImage(image.transform(withNewColor: color), for: .normal)
            }else{
                //button.setImage(#imageLiteral(resourceName: "icon-hotel"), for: .normal)
            }
        }
        if let btn = getSearchBarButton() {
            let button = btn.value(forKey: "_clearButton") as! UIButton
            if let image = button.imageView?.image {
                button.setImage(image.transform(withNewColor: color), for: .normal)
            }else{
                //button.setImage(#imageLiteral(resourceName: "icon-hotel"), for: .normal)
            }
        }

    }

    func setSearchImageColor(color: UIColor) {
        if let imageView = getSearchBarTextField()?.leftView as? UIImageView {
            imageView.image = imageView.image?.transform(withNewColor: color)
        }
    }
}

extension UIImage {

    func transform(withNewColor color: UIColor) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(size, false, scale)

        let context = UIGraphicsGetCurrentContext()!
        context.translateBy(x: 0, y: size.height)
        context.scaleBy(x: 1.0, y: -1.0)
        context.setBlendMode(.normal)

        let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
        context.clip(to: rect, mask: cgImage!)

        color.setFill()
        context.fill(rect)

        let newImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return newImage
    }
}

4 个答案:

答案 0 :(得分:1)

我找到了答案,请找到相同的

下面的代码
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {

        if let searchTextField = searchBar.value(forKey: "searchField") as? UITextField , let clearButton = searchTextField.value(forKey: "_clearButton")as? UIButton {

            if let img3 = clearButton.image(for: .highlighted) {
                clearButton.isHidden = false
                let tintedClearImage = img3.imageWithColor(color1: UIColor.white)
                clearButton.setImage(tintedClearImage, for: .normal)
                clearButton.setImage(tintedClearImage, for: .highlighted)
            }else{
               clearButton.isHidden = true
            }               
        }            
    }

enter image description here 为项目中的图像颜色更改添加以下扩展名。

extension UIImage {
    func imageWithColor(color1: UIColor) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
        color1.setFill()

        let context = UIGraphicsGetCurrentContext()
        context?.translateBy(x: 0, y: self.size.height)
        context?.scaleBy(x: 1.0, y: -1.0)
        context?.setBlendMode(CGBlendMode.normal)

        let rect = CGRect(origin: .zero, size: CGSize(width: self.size.width, height: self.size.height))
        context?.clip(to: rect, mask: self.cgImage!)
        context?.fill(rect)

        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return newImage!
    }
}

答案 1 :(得分:1)

您可以使用自定义图标,它可以在iOS 11中使用,

代码段:

searchBar.setImage(UIImage(named: "ic_clear"), for: .clear, state: .normal)

答案 2 :(得分:0)

这是我的解决方案: 我的代码尝试更改 ios 文本字段清除按钮颜色。

但在某些 IOS 版本中 UIButton 键 "_clearButton" 返回 nil 因为它在高 IOS 版本中注册。 我已经测试了它在 IOS 14 中工作的扩展,但在 IOS 12.4 文本字段清除按钮没有改变颜色。我调试并识别出 forKey: "_clearButton" 在 IOS 12.4 中返回 nil

我的解决方案尝试获取 clearbutton 图像,如果它为零,则使用自定义图像并更改其颜色

extension UITextField{
    var clearButton : UIButton{
        return self.value(forKey: "_clearButton") as! UIButton

    }
    
    var clearButtonTintColor: UIColor? {
           get {
               return clearButton.tintColor
           }
           set {
             var image = clearButton.imageView?.image
                
            if image == nil{
                image = UIImage(named: "clear_field")//this is custom image
            }
        
                image =  image?.withRenderingMode(.alwaysTemplate)
               clearButton.setImage(image, for: .normal)
               clearButton.tintColor = newValue
         
           }
       }
}

改变颜色使用这个:

textField.clearButtonTintColor = UIColor(rgb: 0x753a3a)

Here is a similiar official clear button image

答案 3 :(得分:-1)

如何更改 clearButton 的颜色?

iOS 11 解决方案:

不幸的是,在 iOS 11 中,我们无法以编程方式更改清除按钮的渲染模式(我不知道为什么)。首先以编程方式设置新的清晰图标图像,然后转到 Assets 文件夹并手动更改图标的渲染模式。

let clearButton = textFieldInsideSearchBar?.value(forKey: “clearButton”) as! UIButton
clearButton.setImage(UIImage(named: "ic_clear"), for: .normal)
clearButton.tintColor = .white

iOS 10 及更低版本:

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