i also try to change with "searchController.searchBar.searchTextField.tintColor = .white"
but it's not working issue facing after xcode 13 update.
Try to create a custom searchController and into the setup to change the tintColor of all the subviews that are different of UIButton .
Here an example :
class CustomSearchController: UISearchController {
var placeHolder:String?
private var catalogSearchBar = CatalogSearchBar()
override public var searchBar: UISearchBar {
get {
catalogSearchBar.placeholder = placeHolder
return catalogSearchBar
}
}
}
class CatalogSearchBar: UISearchBar {
init() {
super.init(frame: .zero)
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
override func layoutSubviews() {
super.layoutSubviews()
setup()
}
private func setup() {
backgroundColor = Constants.shared.navigationBar.lightModeBgColor
// text field
let textField = searchTextField
textField.subviews.forEach { (view) in
if ((view as? UIButton) != nil) {
view.tintColor = UIColor.white
}
}
textField.frame.size.height = 35
self.searchTextPositionAdjustment = UIOffset(horizontal: 4, vertical: 0)
textField.layer.cornerRadius = 15
textField.placeholder = self.placeholder
textField.attributedPlaceholder = NSAttributedString(string: self.placeholder != nil ? self.placeholder! : "", attributes: [NSAttributedString.Key.foregroundColor: UIColor.white])
textField.layer.masksToBounds = true
textField.layer.backgroundColor = UIColor.white.withAlphaComponent(0.25).cgColor
if let view = textField.value(forKey: "backgroundView") as? UIView {
view.removeFromSuperview()
}
textField.font = UIFont(name: "Montserrat-Regular", size: 15)
textField.textColor = UIColor.white
textField.tintColor = UIColor.white
// search icon
let leftView: UIView = {
let image = UIImage(named: "search")
let padding = 8
let size = 20
let outerView = UIView(frame: CGRect(x: 0, y: 0, width: size + padding, height: size) )
let iconView = UIImageView(frame: CGRect(x: padding, y: 0, width: size, height: size))
iconView.tintColor = UIColor.white
iconView.image = image
outerView.addSubview(iconView)
return outerView
}()
textField.leftView = leftView
}
}
I really thought it would be easy to set the background color of my UISearchBar's text field to white. But no matter what I try, it always stays offwhite / light gray (#efeff0).
import UIKit
class ViewController: UIViewController {
private let searchController = UISearchController()
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = "Hello World"
view.backgroundColor = #colorLiteral(red: 0.9588784575, green: 0.9528519511, blue: 0.9350754619, alpha: 1)
searchController.searchBar.searchTextField.backgroundColor = .white
navigationItem.searchController = searchController
}
}
How can I make the search bar have a pure white background color? App is iOS 13+, if that helps.
Tiny test project: https://github.com/kevinrenskers/WhiteSearch.
It's possible. Set the background of the search field with a white image.
let size = CGSize(width: searchController.searchBar.frame.size.width - 12, height: searchController.searchBar.frame.size.height - 12)
let backgroundImage = createWhiteBG(size)!
let imageWithCorner = backgroundImage.createImageWithRoundBorder(cornerRadiuos: 10)!
searchController.searchBar.setSearchFieldBackgroundImage(imageWithCorner, for: UIControl.State.normal)
If you don't want to input an image to app. Try this for create one programmatically.
func createWhiteBG(_ frame : CGSize) -> UIImage? {
var rect = CGRect(x: 0, y: 0, width: 0, height: 0)
rect.size = frame
UIGraphicsBeginImageContext(rect.size)
let context = UIGraphicsGetCurrentContext()
context?.setFillColor(UIColor.white.cgColor)
context?.fill(rect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
extension UIImage {
func createImageWithRoundBorder(cornerRadiuos : CGFloat) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(self.size, false, scale)
let rect = CGRect(origin:CGPoint(x: 0, y: 0), size: self.size)
let context = UIGraphicsGetCurrentContext()
let path = UIBezierPath(
roundedRect: rect,
cornerRadius: cornerRadiuos
)
context?.beginPath()
context?.addPath(path.cgPath)
context?.closePath()
context?.clip()
self.draw(at: CGPoint.zero)
context?.restoreGState()
path.lineWidth = 1.5
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
}
Try this ... Change colors and images according to your preference
DispatchQueue.main.async {
searchBar.backgroundImage = UIImage()
for s in searchBar.subviews[0].subviews {
if s is UITextField {
s.layer.borderWidth = 1.0
s.layer.borderColor = UIColor.lightGray.cgColor
}
}
let searchTextField:UITextField = searchBar.subviews[0].subviews.last as? UITextField ?? UITextField()
searchTextField.layer.cornerRadius = 10
searchTextField.textAlignment = NSTextAlignment.left
let image:UIImage = UIImage(named: "search")!
let imageView:UIImageView = UIImageView.init(image: image)
searchTextField.leftView = nil
searchTextField.placeholder = "Search..."
searchTextField.font = UIFont.textFieldText
searchTextField.rightView = imageView
searchTextField.rightViewMode = UITextField.ViewMode.always
}
Here is My complete Custom Search Bar Which you can define the searchbar backgroundColor and TextField background Color
Tested
import Foundation
class SearchBar: UISearchBar {
override init(frame: CGRect) {
super.init(frame: frame)
makeUI()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
makeUI()
}
private func makeUI( ) {
//SearchBar BackgroundColor
self.backgroundImage = UIImage(color: UIColor.white)
//Border Width
self.layer.borderWidth = 1
//Border Color
self.layer.borderColor = UIColor("DEDEDE")?.cgColor
//Corner Radius
self.layer.cornerRadius = 3
self.layer.masksToBounds = true
//Change Icon
self.setImage(UIImage(named: "search")?
.byResize(to: CGSize(width: 30, height: 30)), for: .search, state: .normal)
if let searchTextField = self.value(forKey: "searchField") as? UISearchTextField {
//TextField Background !!!!!
searchTextField.backgroundColor = UIColor.white
//TextField Font
searchTextField.font = UIFont(name: "Poppins-Regular", size: 21)
searchTextField.textColor = .black
}
}
}
I want to customize background color and text color of the search bar, I have tried following code for the make customize but no luck.
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
}
}
It is working only when I used UISearchbar only, but not working when it is UISearchController.
Please find below image for more understanding. I need text/placeholder color white. and clear/search image color white.
I have used the code below.
self.title = "Skills"
self.navigationController?.navigationBar.prefersLargeTitles = true
self.navigationController?.isNavigationBarHidden = false
self.navigationController?.navigationBar.barTintColor = UIColor.hexString("6EC280") //light green
self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
self.navigationController?.navigationBar.largeTitleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
//SEARCH BAR CUSTOMIZATION
let btnBack = UIButton(frame: CGRect(x: 0, y: 0, width: 30.0, height: 50.0))
btnBack.setImage(#imageLiteral(resourceName: "chevron-back"), for: .normal)
btnBack.addTarget(self, action: #selector(btnBack(_:)), for: .touchUpInside)
let BarItem = UIBarButtonItem(customView: btnBack)
navigationItem.leftBarButtonItem = BarItem
UISearchBar.appearance().tintColor = UIColor.white
UINavigationBar.appearance().tintColor = UIColor.white
searchBarController.searchResultsUpdater = self
searchBarController.obscuresBackgroundDuringPresentation = false
navigationItem.searchController = searchBarController
navigationItem.hidesSearchBarWhenScrolling = false
definesPresentationContext = true
searchBarController.searchBar.placeholder = "Search"
searchBarController.searchBar.setTextColor(color: .white)
searchBarController.searchBar.setPlaceholderTextColor(color: .white)
searchBarController.searchBar.setSearchImageColor(color: .white)
searchBarController.searchBar.setTextFieldColor(color: UIColor.hexString("549C64")) //light green
searchBarController.searchBar.delegate = self
I have put the code in the main queue and its work.
DispatchQueue.main.async {
self.searchBarController.searchBar.placeholder = "Search"
self.searchBarController.searchBar.setTextColor(color: .white)
self.searchBarController.searchBar.setPlaceholderTextColor(color: .white)
self.searchBarController.searchBar.setSearchImageColor(color: .white)
self.searchBarController.searchBar.setTextFieldColor(color: UIColor.clear) //light green
self.searchBarController.searchBar.delegate = self
}
Strange :)
In your AppDelegate, in didFinishLaunchingWithOptions function add the following lines of code:
UISearchBar.appearance().tintColor = .green // Add your color
UISearchBar.appearance().backgroundColor = .white // Add your color
I ma trying to make search bar transparent in swift 4.
Here is my code
let searchBar = UISearchBar()
searchBar.sizeToFit()
searchBar.placeholder = "search
searchBar.isTranslucent = true
searchBar.barTintColor = UIColor.clear
searchBar.backgroundColor = UIColor.clear
self.tabBarController?.navigationItem.titleView = searchBar
It ia appears like this
I want to implement search bar as in screenshot.
Please can anyone suggest me on this.
Try this code:
searchBar.setSearchFieldBackgroundImage(UIImage(), for: .normal)
or:
UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).backgroundColor = .clear
completely transparent all part of uisearchbar :
searchBar.setSearchFieldBackgroundImage(UIImage(), for: .normal)
searchBar.setBackgroundImage(UIImage(), for: .any, barMetrics: .default)
searchBar is an outlet of UISearchBar from storyBoard
#IBOutlet weak var searchBarView:UISearchBar!
searchBarView.placeholder = textStr
searchBarView.setTextColor(color: .white)
searchBarView.layer.borderWidth = 1
searchBarView.layer.borderColor = searchBarView.barTintColor?.cgColor //orange
searchBarView.setTextFieldColor(color: .clear)
searchBarView.setPlaceholderTextColor(color: .white)
searchBarView.setSearchImageColor(color: .white)
searchBarView.setTextFieldClearButtonColor(color: .white)
//MARK: - UISearchBar EXTENSION
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 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 = 6
case .prominent, .default:
textField.backgroundColor = color
}
}
}
func setPlaceholderTextColor(color: UIColor) {
if let textField = getSearchBarTextField() {
textField.attributedPlaceholder = NSAttributedString(string: self.placeholder != nil ? self.placeholder! : "", attributes: [NSForegroundColorAttributeName: 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)
}
}
}
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
}
}
I can set the background color for a button but I can't work out how to set the background color for UIControlState.Highlighted. Is it even possible? or do I need to go down the setBackgroundImage path?
If anyone stops by, another way to go maybe more easily if it is something you need more than once... I wrote a short extension for UIButton, it works just fine:
for Swift 3
extension UIButton {
func setBackgroundColor(color: UIColor, forState: UIControlState) {
UIGraphicsBeginImageContext(CGSize(width: 1, height: 1))
CGContextSetFillColorWithColor(UIGraphicsGetCurrentContext(), color.CGColor)
CGContextFillRect(UIGraphicsGetCurrentContext(), CGRect(x: 0, y: 0, width: 1, height: 1))
let colorImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
self.setBackgroundImage(colorImage, forState: forState)
}
}
for Swift 4
extension UIButton {
func setBackgroundColor(color: UIColor, forState: UIControl.State) {
self.clipsToBounds = true // add this to maintain corner radius
UIGraphicsBeginImageContext(CGSize(width: 1, height: 1))
if let context = UIGraphicsGetCurrentContext() {
context.setFillColor(color.cgColor)
context.fill(CGRect(x: 0, y: 0, width: 1, height: 1))
let colorImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
self.setBackgroundImage(colorImage, for: forState)
}
}
}
You use it just like setBackgroundImage:
yourButton.setBackgroundColor(color: UIColor.white, forState: UIControl.State.highlighted)
Syntax changes to #winterized extension for Swift 3+ syntax
extension UIButton {
func setBackgroundColor(color: UIColor, forState: UIControlState) {
UIGraphicsBeginImageContext(CGSize(width: 1, height: 1))
UIGraphicsGetCurrentContext()!.setFillColor(color.cgColor)
UIGraphicsGetCurrentContext()!.fill(CGRect(x: 0, y: 0, width: 1, height: 1))
let colorImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
self.setBackgroundImage(colorImage, for: forState)
}}
Below will be one way to go. Two IBActions. One to control background color when depressing a button, one on release.
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var button: UIButton!
#IBAction func buttonClicked(sender: AnyObject) { //Touch Up Inside action
button.backgroundColor = UIColor.whiteColor()
}
#IBAction func buttonReleased(sender: AnyObject) { //Touch Down action
button.backgroundColor = UIColor.blueColor()
}
override func viewDidLoad() {
super.viewDidLoad()
}
}
When you look at the autocomplete options for your button after adding a period, you can set a background color, but not for specified state. You can only set background images. Now of course if you are married to doing it this way instead of using the method I show above, you could load an image of the desired color as the background image using the setbackgroundImageForState property.
Swift 4+ compatibility for the accepted answer :
extension UIButton {
/// Sets the background color to use for the specified button state.
func setBackgroundColor(color: UIColor, forState: UIControlState) {
let minimumSize: CGSize = CGSize(width: 1.0, height: 1.0)
UIGraphicsBeginImageContext(minimumSize)
if let context = UIGraphicsGetCurrentContext() {
context.setFillColor(color.cgColor)
context.fill(CGRect(origin: .zero, size: minimumSize))
}
let colorImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
self.clipsToBounds = true
self.setBackgroundImage(colorImage, for: forState)
}
}
Compatible SwiftLint and fix the bug of broken auto layout / corner radius.
Swift 4 Version of this solution:
extension UIButton {
func setBackgroundColor(_ color: UIColor, for state: UIControlState) {
UIGraphicsBeginImageContext(CGSize(width: 1, height: 1))
UIGraphicsGetCurrentContext()!.setFillColor(color.cgColor)
UIGraphicsGetCurrentContext()!.fill(CGRect(x: 0, y: 0, width: 1, height: 1))
let colorImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
setBackgroundImage(colorImage, for: state)
}
}
Seems nobody here has mentioned using Key Value Observation yet, but it's another approach.
A reason for doing so instead of picking the other answers here is you don't need to go creating new images all the time nor be concerned with secondary effects of assigning images to buttons (e.g. cornerRadius effects).
But you'll need to create a class for the observer, who would be responsible for storing the different background colours and applying them in the observeValue() method.
public class ButtonHighlighterObserver: NSObject {
var observedButton:UIButton? = nil
var backgroundColor: UIColor = UIColor.white
var backgroundHighlightColor: UIColor = UIColor.gray
public override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
// Perform background color changes when highlight state change is observed
if keyPath == "highlighted", object as? UIButton === observedButton {
observedButton!.backgroundColor = observedButton!.isHighlighted ? self.backgroundHighlightColor : self.backgroundColor
}
}
}
Then all you need to do is manage addObserver / removeObserver during operation:
// Add observer to button's highlighted value
button.addObserver(anObserver, forKeyPath: "highlighted", options: [.new], context: nil)
anObserver.observedButton = button
// ...
// And at deinit time, be sure you remove the observer again
anObserver.observedButton?.removeObserver(item, forKeyPath: "highlighted")
anObserver.observedButton = nil
Update Swift 4
extension UIButton {
func setBackgroundColor(color: UIColor, forState: UIControlState) {
UIGraphicsBeginImageContext(CGSize(width: 1, height: 1))
UIGraphicsGetCurrentContext()!.setFillColor(color.cgColor)
UIGraphicsGetCurrentContext()!.fill(CGRect(x: 0, y: 0, width: 1, height: 1))
let colorImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
self.setBackgroundImage(colorImage, for: forState)
}
Event
Button Action
Show Touch On Hightlight
Why not?
#implementation UIButton (Color)
- (void) setBackgroundColor:(UIColor*)color forState:(UIControlState)state
{
[self setBackgroundImage:[UIImage.alloc initWithCIImage:[CIImage imageWithColor:[CIColor colorWithCGColor:color.CGColor]]] forState:state];
}
#end
You can override isHighlighted and changed the background color when the isHighlighted is set.
Example: TextButton.Swift
import UIKit
class TextButton: UIButton {
private var text: String = "Submit" {
didSet{
setText()
}
}
var hightlightedColor : UIColor = UIColor(red: 50/255, green: 50/255, blue: 50/255, alpha: 1)
var background :UIColor = .black {
didSet{
self.backgroundColor = background
}
}
override var isHighlighted: Bool {
didSet {
self.backgroundColor = self.isHighlighted ? hightlightedColor : background
}
}
// MARK: - Lifecycle
override init(frame: CGRect) {
super.init(frame: frame)
sharedLayout()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
sharedLayout()
}
// MARK: - Method
private func setText() {
self.setTitle(text, for: .normal)
}
private func sharedLayout() {
self.setTitle(text, for: .normal)
self.backgroundColor = self.isHighlighted ? .green : background
self.layer.cornerRadius = 8
}
}
Usages:
let nextBtn = TextButton()
in Swift 5
For those who don't want to use colored background to beat the selected state
Simply you can beat the problem by using #Selector & if statement to change the UIButton colors for each state individually easily
For Example:
override func viewDidLoad() {
super.viewDidLoad()
//to reset the button color to its original color ( optionally )
self.myButtonOutlet.backgroundColor = UIColor.white
}
#IBOutlet weak var myButtonOutlet: UIButton!{
didSet{ // Button selector and image here
self.myButtonOutlet.setImage(UIImage(systemName: ""), for: UIControl.State.normal)
self.myButtonOutlet.setImage(UIImage(systemName: "checkmark"), for: UIControl.State.selected)
self.myButtonOutlet.addTarget(self, action: #selector(tappedButton), for: UIControl.Event.touchUpInside)
}
}
#objc func tappedButton() { // Colors selection is here
if self.myButtonOutlet.isSelected == true {
self.myButtonOutlet.isSelected = false
self.myButtonOutlet.backgroundColor = UIColor.white
} else {
self.myButtonOutlet.isSelected = true
self.myButtonOutlet.backgroundColor = UIColor.black
self.myButtonOutlet.tintColor00 = UIColor.white
}
}
If using storyboard or xib use #IBInspectable by adding extension for UIButton
import Foundation
import UIKit
import ObjectiveC
// Declare a global var to produce a unique address as the assoc object handle
var highlightedColorHandle: UInt8 = 0
extension UIButton {
func setBackgroundColor(_ color: UIColor, for state: UIControl.State) {
self.setBackgroundImage(UIImage.init(color: color), for: state)
}
#IBInspectable
var highlightedBackground: UIColor? {
get {
if let color = objc_getAssociatedObject(self, &highlightedColorHandle) as? UIColor {
return color
}
return nil
}
set {
if let color = newValue {
self.setBackgroundColor(color, for: .highlighted)
objc_setAssociatedObject(self, &highlightedColorHandle, color, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
} else {
self.setBackgroundImage(nil, for: .highlighted)
objc_setAssociatedObject(self, &highlightedColorHandle, nil, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
}
}
Use in Storyboard or Xib like
Swift 5
In my case I needed something else, because the option with the extension and setBackgroundColor function doesn't work properly in case when we have different background button colors for dark/light mode and when we change traitCollection.userInterfaceStyle (dark/light mode). So I used custom implementation of UIButton class and override properties isHighlighted and isEnabled :
import UIKit
class CustomButton: UIButton {
override init(frame: CGRect) {
super.init(frame: frame)
self.isEnabled = isEnabled
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override var isHighlighted: Bool {
didSet {
self.backgroundColor = isHighlighted ? UIColor.blue : UIColor.cyan
}
}
override var isEnabled: Bool {
didSet {
self.backgroundColor = isEnabled ? UIColor.cyan : UIColor.red
}
}
}