Skip to content

Instantly share code, notes, and snippets.

@wavecos
Last active November 19, 2021 00:09
Show Gist options
  • Select an option

  • Save wavecos/970a0e0bad82d258c22c to your computer and use it in GitHub Desktop.

Select an option

Save wavecos/970a0e0bad82d258c22c to your computer and use it in GitHub Desktop.
Customize Color, background from UISearchBar in Swift

Customize Color, background from UISearchBar in Swift

// as UISearchBar extension
extension UISearchBar {
  func changeSearchBarColor(color : UIColor) {
    for subView in self.subviews {
      for subSubView in subView.subviews {
        if subSubView.conformsToProtocol(UITextInputTraits.self) {
          let textField = subSubView as UITextField
          textField.backgroundColor = color
          break
        }
      }
    }
  }
}
@highthem

highthem commented Mar 5, 2016

Copy link
Copy Markdown

not working :(

@mshhmzh

mshhmzh commented Oct 9, 2016

Copy link
Copy Markdown

let searchBar = UISearchBar(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 50))
//ColorImage is an image with background color
searchBar.setSearchFieldBackgroundImage(UIImage(named: "ColorImage"), for: UIControlState.normal)

this code work on iOS 10, Swift 3.0

@davidphan75

davidphan75 commented Jan 21, 2017

Copy link
Copy Markdown
// as UISearchBar extension
extension UISearchBar {
    func changeSearchBarColor(color : UIColor) {
        for subView in self.subviews {
            for subSubView in subView.subviews {
                
                if let _ = subSubView as? UITextInputTraits {
                    let textField = subSubView as! UITextField
                    textField.backgroundColor = color
                    break
                }
                
            }
        }
    }
}

Updated original code for Swift 3.0

@shev-vadim-net

Copy link
Copy Markdown

The solution with subviews doesn't work for me. So here's my extension:

extension UISearchBar {
    func changeSearchBarColor(color: UIColor) {
        UIGraphicsBeginImageContext(self.frame.size)
        color.setFill()
        UIBezierPath(rect: self.frame).fill()
        let bgImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        
        self.setSearchFieldBackgroundImage(bgImage, for: .normal)
    }
}

@astrokin

astrokin commented Aug 7, 2017

Copy link
Copy Markdown
public extension UISearchBar {
  public func setStyleColor(_ color: UIColor) {
    tintColor = color
    guard let tf = (value(forKey: "searchField") as? UITextField) else { return }
    tf.textColor = color
    if let glassIconView = tf.leftView as? UIImageView, let img = glassIconView.image {
      let newImg = img.blendedByColor(color)
      glassIconView.image = newImg
    }
    if let clearButton = tf.value(forKey: "clearButton") as? UIButton {
      clearButton.setImage(clearButton.imageView?.image?.withRenderingMode(.alwaysTemplate), for: .normal)
      clearButton.tintColor = color
    }
  }
}

extension UIImage {
  
  public func blendedByColor(_ color: UIColor) -> UIImage {
    let scale = UIScreen.main.scale
    if scale > 1 {
      UIGraphicsBeginImageContextWithOptions(size, false, scale)
    } else {
      UIGraphicsBeginImageContext(size)
    }
    color.setFill()
    let bounds = CGRect(x: 0, y: 0, width: size.width, height: size.height)
    UIRectFill(bounds)
    draw(in: bounds, blendMode: .destinationIn, alpha: 1)
    let blendedImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return blendedImage!
  }
}

works perfectly

@patiljignesh

Copy link
Copy Markdown

@shev-vadim-net Thanks!

@chanonly123

chanonly123 commented Aug 20, 2018

Copy link
Copy Markdown
extension UISearchBar {
    func changeSearchBarColor(fieldColor: UIColor, backColor: UIColor, borderColor: UIColor?) {
        UIGraphicsBeginImageContext(bounds.size)
        backColor.setFill()
        UIBezierPath(rect: bounds).fill()
        setBackgroundImage(UIGraphicsGetImageFromCurrentImageContext()!, for: UIBarPosition.any, barMetrics: .default)
        
        let newBounds = bounds.insetBy(dx: 0, dy: 8)
        fieldColor.setFill()
        let path = UIBezierPath(roundedRect: newBounds, cornerRadius: newBounds.height / 2)
        
        if let borderColor = borderColor {
            borderColor.setStroke()
            path.lineWidth = 1 / UIScreen.main.scale
            path.stroke()
        }
        
        path.fill()
        setSearchFieldBackgroundImage(UIGraphicsGetImageFromCurrentImageContext()!, for: UIControlState.normal)
        
        UIGraphicsEndImageContext()
    }
}

@SeRG1k17

SeRG1k17 commented Nov 19, 2018

Copy link
Copy Markdown
extension UISearchBar {
    
    var textField: UITextField? {
        
        return subviews.map { $0.subviews.first(where: { $0 is UITextInputTraits}) as? UITextField }
            .compactMap { $0 }
            .first
    }
}

//Usage:
let bar = UISearchBar()
bar.textField?.backgroundColor = .red

@hechukwu

hechukwu commented Oct 14, 2019

Copy link
Copy Markdown

extension UISearchBar { func changeSearchBarColor(color: UIColor) { UIGraphicsBeginImageContext(self.frame.size) color.setFill() UIBezierPath(rect: self.frame).fill() let bgImage = UIGraphicsGetImageFromCurrentImageContext()! UIGraphicsEndImageContext() self.setSearchFieldBackgroundImage(bgImage, for: .normal) } }
This works for me but the color goes outside the textfield bounds how can I make it stay within the textfield.
PS: I have set clipToBounds to be true and everything I could think of and my searchbar is minimal

@dimabiserov

Copy link
Copy Markdown

extension UISearchBar { func changeSearchBarColor(color: UIColor) { UIGraphicsBeginImageContext(self.frame.size) color.setFill() UIBezierPath(rect: self.frame).fill() let bgImage = UIGraphicsGetImageFromCurrentImageContext()! UIGraphicsEndImageContext() self.setSearchFieldBackgroundImage(bgImage, for: .normal) } }

did you find a solution?

@hechukwu

hechukwu commented Jan 7, 2020

Copy link
Copy Markdown

@hell4opt Yeah I did for the size I had to do this let size = CGSize(width: self.frame.size.width, height: 45) you have to play with the height till you get what you want.

@hechukwu

hechukwu commented Jan 7, 2020

Copy link
Copy Markdown
This is my full code for anyone having the same issue
extension UISearchBar {
  func changeSearchBarColor(color: UIColor, size: CGSize) {
        UIGraphicsBeginImageContext(self.frame.size)
        color.setFill()
        UIBezierPath(rect: self.frame).fill()
        let bgImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        self.setSearchFieldBackgroundImage(bgImage, for: .normal)
    }
}

Then you call it like so yourSearchBar.changeSearchBarColor(color: yellow, size: CGSize(width: yourSearchBar.frame.size.width, height: 45))

@dimabiserov

Copy link
Copy Markdown
This is my full code for anyone having the same issue
extension UISearchBar {
  func changeSearchBarColor(color: UIColor, size: CGSize) {
        UIGraphicsBeginImageContext(self.frame.size)
        color.setFill()
        UIBezierPath(rect: self.frame).fill()
        let bgImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        self.setSearchFieldBackgroundImage(bgImage, for: .normal)
    }
}

Then you call it like so yourSearchBar.changeSearchBarColor(color: yellow, size: CGSize(width: yourSearchBar.frame.size.width, height: 45))

thanks!) but the height does not work (and the corner radius is not enough)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment