【问题标题】:Can I change colour/image UISearchBar clear button?我可以更改颜色/图像 UISearchBar 清除按钮吗?
【发布时间】:2018-05-17 05:10:20
【问题描述】:

我想将清除按钮颜色更改为白色。我尝试了很多方法,但没有运气。:(我还参考了以下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
    }
}

【问题讨论】:

标签: ios swift4 uisearchbar


【解决方案1】:

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

代码:

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

【讨论】:

    【解决方案2】:

    我找到了答案,请在下面找到相同的代码

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

    在您的项目中添加以下图像颜色更改扩展。

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

    【讨论】:

    • 第一次没有反映
    • @Anbu.Karthik 这可能是一个线程问题,在图像实际初始化之前调用回调。我使用了DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) { ... },它解决了这个问题。
    • @Gyfis - 我会尽力让你知道
    • @Anbu.Karthik 对我来说,不幸的是,一旦我从另一个屏幕返回,取消图标的颜色就变回了灰色,所以这个解决方案仍然存在一些粗糙的边缘
    • self.value(forKey: "_clearButton") as? UIButton 似乎是未记录的行为,并且可能会随着任何 Apple SDK 更新而改变。我不建议使用它。
    【解决方案3】:

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

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

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

    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

    【讨论】:

      【解决方案4】:

      如何更改 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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-29
        • 2015-02-24
        • 1970-01-01
        • 1970-01-01
        • 2015-03-12
        • 2021-04-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多