I'm trying to create a search bar like this:
But I'm noticing that I'm probably going to have to replace the search bar with my own image because the search bar corners comes out wrong when I set:
self.searchController.searchBar.layer.cornerRadius = 50 // I've tried other numbers besides this too with no luck
self.searchController.searchBar.clipsToBounds = true
If I set this:
self.searchController.searchBar.layer.cornerRadius = self.searchController.searchBar.bounds.height/2
The search bar comes out like this:
Which still isn't exact like in the image.
Is there a way to replace the left and right side of the textfield with an image that way I can use the rounded corners from my custom search bar?
I am using this code UISearchBar but you can use this code with UISearchController.
let searchBar = UISearchBar()
searchBar.sizeToFit()
searchBar.placeholder = "Search"
navigationItem.titleView = searchBar
if let textfield = searchBar.value(forKey: "searchField") as? UITextField {
textfield.textColor = UIColor.blue
if let backgroundview = textfield.subviews.first {
// Background color
backgroundview.backgroundColor = UIColor.white
// Rounded corner
backgroundview.layer.cornerRadius = 14;
backgroundview.clipsToBounds = true;
}
}
You should change the radius of searchTextField inside UISearchBar .
you can do that like this :
searchBar.searchTextField.layer.cornerRadius = 20
searchBar.searchTextField.layer.masksToBounds = true
* searchBar is an outlet of UISearchBar from storyBoard
The issue here is you are setting the corner radius on the UISearchBar, not the UITextField inside it. You can do some sort of hack to get the UITextField, but that's not really recommended.
As you mentioned in your question, you'll need to use custom images and the methods shown here: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UISearchBar_Class/#//apple_ref/doc/uid/TP40007529-CH3-SW40
This IS working for me in swift 3 iOS 10:
searchController.searchBar.layer.cornerRadius = 20
searchController.searchBar.clipsToBounds = true
ez way for searchbarview
for subview & POPUPs [Swift 5]
override func layoutSublayers(of layer: CALayer) {
searchBarPopup.clipsToBounds = true
searchBarPopup.layer.cornerRadius = 10
searchBarPopup.layer.maskedCorners = [ .layerMaxXMinYCorner, .layerMinXMinYCorner]
}
Related
Hello I'm trying to change the UISearchbar to rectangular shape rather then rounded rectangular and merge it with the navigation bar with same color.
The background color of the navigation bar should be the same as the background of the search bar but there's difference and also there's a clear edge shown both should show the background color #be1b25 and not the #bc303a. As well the textfield still showing rounded rectangle and not fully rectangle.
The Main View Controller code
#IBOutlet weak var searchBar: UISearchBar!
self.navigationController?.navigationBar.isTranslucent = true
navigationController?.navigationBar.backgroundColor = UIColor().HexToColor(hexString: REDCOLOR)
searchBar.backgroundColor = UIColor().HexToColor(hexString: REDCOLOR)
searchBar.tintColor = UIColor().HexToColor(hexString: REDCOLOR)
searchBar.barTintColor = UIColor().HexToColor(hexString: REDCOLOR)
searchBar.barStyle = .default
searchBar.placeholder = NetworkManager.sharedInstance.language(key: "searchentirestore")
searchBar.layer.cornerRadius = 0;
searchBar.clipsToBounds = false;
searchBar.barTintColor = UIColor().HexToColor(hexString: REDCOLOR)
searchBar.layer.borderWidth = 0
//searchBar.layer.borderColor = UIColor.clear as! CGColor
The UISearchBar Extension
extension UISearchBar {
private var textField: UITextField? {
return subviews.first?.subviews.flatMap { $0 as? UITextField }.first
}
private var activityIndicator: UIActivityIndicatorView? {
return textField?.leftView?.subviews.flatMap{ $0 as? UIActivityIndicatorView }.first
}
var isLoading: Bool {
get {
return activityIndicator != nil
} set {
if newValue {
if activityIndicator == nil {
let newActivityIndicator = UIActivityIndicatorView(activityIndicatorStyle: .gray)
newActivityIndicator.transform = CGAffineTransform(scaleX: 0.7, y: 0.7)
newActivityIndicator.startAnimating()
newActivityIndicator.color = UIColor().HexToColor(hexString: BUTTON_COLOR)
newActivityIndicator.backgroundColor = UIColor.white
textField?.leftView?.addSubview(newActivityIndicator)
let leftViewSize = textField?.leftView?.frame.size ?? CGSize.zero
newActivityIndicator.center = CGPoint(x: leftViewSize.width/2, y: leftViewSize.height/2)
}
} else {
activityIndicator?.removeFromSuperview()
}
}
}
Any help please, this is Swift 3. Thanks in advance
so there a few things you are dealing with
1 Rectangular UISearchbar
either you will traverse subviews of native UISearchbar and change its right sublayers corner radiuses, but this is a hack, Apple can change that hierarchy and you will be at the beginning again
you can create your own component that will look like UISearchbar, few UIViews, and UITextfield with some UIImageViews.
there are few libraries on GitHub you can use https://github.com/CosmicMind/Samples
there is also a similar question here iOS 11 UISearchBar in UINavigationBar
2 Merge with NavBar
one way is to use UISearchController with iOS 11
or you can with your custom UISearchbar you can either add it below the NavBar in UIView, not in navigation, but the NavBar cannot be translucent in this case, because you will never achieve the same color space
you can add your custom view as custom UIView into titleView in NavBar
Extend the UISearchBar and apply the customization.
Set the UISearchBar as titleView to the NavigationController
class SearchField: UISearchBar {
override init(frame: CGRect) {
super.init(frame: frame)
// Corner radius
self.layer.cornerRadius = 2.0
self..clipsToBounds = true
// Textfield inside color.
if let searchTextField = self.value(forKey: "_searchField") as? UITextField {
// Set TextField property
// Set the corner radius for TextField (not suggested)
if let clearButton = searchTextField.value(forKey: "_clearButton") as? UIButton {
// Set the clear button property
}
}
}
}
// Use it in the ViewController.
let searchBar = SearchField()
self.navigationItem.titleView = searchBar
When searchbar is in inactive state and the placeholder is too big, the magnifying glass icon goes outside the searchbar. Anyone knows how to fix this? Nothing
lazy var searchBar: UISearchBar = {
let searchBar = UISearchBar()
searchBar.autocorrectionType = .yes
searchBar.autocapitalizationType = .none
searchBar.placeholder = ChangeToLanguage(SEARCH_LABEL_PLACEHOLDER_SEARCHMODULES)
searchBar.delegate = self
searchBar.isTranslucent = false
let searchBarTextField = searchBar.value(forKey: "searchField") as? UITextField
searchBarTextField?.tintColor = GlobalTintColor
searchBar.barTintColor = GlobalTintColor
return searchBar
}()
Try adjusting the position of search bar icon by grabbing the UITextField attached to UISearchBar as mentioned in this post.
https://stackoverflow.com/a/36594565/2740582
I understand that this question has been asked many, many times on SO. However, as Apple does best, with the release of iOS 11, they seem to have made a seemingly unnecessary change to the UISearchBar, specifically it's view hierarchy.
In further, the "text field" of a search bar is no longer accessible in the search bar's subviews, causing all of the previous solutions to "access" and change the background color of the text field, or any property of the text field for that matter.
Does anyone know how to actually adjust the background color of a search bar in iOS 11?
FYI:
I am specifically talking about the color behind the text... which now as of 11 defaults to white unless you specify the search bar style to be minimal.
UPDATE 1:
Since my posting of this question, I still have not found a valid or really any real solution to this issue. The closest I have seem to come is to dive deep into the appearance for instance properties
[[UISearchBar class] appearanceWhenContainedInInstancesOfClasses:(nonnull NSArray<Class<UIAppearanceContainer>> *)]
of the UISearchBar. Playing around with the found UITextField via methods such as the following:
if ([view isKindOfClass:[UITextField class]]) {
return (UITextField*)view;
}
UITextField *searchTextField;
for (UIView *subview in view.subviews) {
searchTextField = [self searchViewForTextFieldBg:subview];
if (searchTextField) {
break;
}
}
return searchTextField;
you can begin drawing a new background view to be placed behind the view. However, the issues I had found too tedious to pursue further were drawing the a view with the correct frame / bounds to mimic exactly the original background.
Hopefully someone can find the actual solution to this problem. Nice miss apple...
I think you may be looking for this, right? But I've it in Swift :(
#IBOutlet weak var sbSearchBar: UISearchBar!
if let textfield = sbSearchBar.value(forKey: "searchField") as? UITextField {
textfield.textColor = UIColor.blue
textfield.backgroundColor = UIColor.yellow
}
Here is result:
This Swift code changes the background color of the text field:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// background color of text field
UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).backgroundColor = .cyan
}
This is the result
let searchBar = UISearchBar(frame: CGRect())
let searchField: UITextField? = searchBar.value(forKey: "searchField") as? UITextField
let searchBarBackground: UIView? = searchBar.value(forKey: "background") as? UIView
// searchBarBackground?.removeFromSuperview()
if searchField != nil {
var frame = searchField?.frame
frame?.size.height = 30
searchField?.frame = frame!
searchField?.backgroundColor = .yellow
}
searchBar.barTintColor = .red
searchBar.delegate = self
searchBar.backgroundColor = .green
Runtime Views Hierarchy
If we set background colors for UISearchBar with code above, we'll see the colored subviews as follow images(click links to see).

backgroundColor for Superview of UISearchBar subviews
We can see the Class Name of green view is UISearchBar in Object inspector.
So, if we use searchBar.backgroundColor = .green, we'll set the backgroundColor of Superview green. Therefore, the UISearchBar instance property backgroundColor will set the superview's background color.
Superview of UISearchBar
barTintColor for UISearchBarBackground
We can see the Class Name of red view is UISearchBarBackground in Object inspector.
However, there's no direct method to access the view, we can use KVC searchBar.value(forKey: "background") as? UIView try to get searchBarBackground.
If we use searchBar.barTintColor = .red, we'll set the backgroundColor of UISearchBarBackground's view red. In order to remove two black border on the tint bar layer, we have to remove the background from superview.
barTintColor of UISearchBar
searchField?.backgroundColor for UITextField
We can see the Class Name of yellow view is _UISearchBarSearchFieldBackgroundView (Subview of UISearchBarTextField) in Object inspector.
There's no direct method to access the searchField, same as searchBarBackground. We can also use KVC searchField: UITextField? = searchBar.value(forKey: "searchField") as? UITextField try to get searchField.
If we use searchField?.backgroundColor = .yellow, we'll set the backgroundColor of UITextField yellow. Therefore, if we want to set text field background color, we have to access the searchField with KVC first
UITextField of UISearchBar
It's much simpler than that in Swift 5.
searchBar.barTintColor = .black
searchBar.searchTextField.backgroundColor = .white
Swift 4-5
searchController.searchBar.barTintColor = .white
I am trying to change the gray area (rectangle area) color of the search bar to a different color (orange). Ive tried using searchBar.barTintColor = but that is only changing the color of the cancel button and not the gray area.
EDIT
class usersVC: UITableViewController, UISearchBarDelegate {
// declare searchBar
var searchBar = UISearchBar()
// default function
override func viewDidLoad() {
super.viewDidLoad()
// implement search bar
searchBar.delegate = self
searchBar.showsCancelButton = true
searchBar.sizeToFit()
searchBar.placeholder = "Search"
searchBar.frame.size.width = self.view.frame.size.width - 30
let searchItem = UIBarButtonItem(customView: searchBar)
self.navigationItem.leftBarButtonItem = searchItem
}
Try this again.
I created this effect by loading a simple image with an orange background, seen below.
searchBar.backgroundImage = UIImage(named: "orange")
Background image:
EDIT 1
Based on your recent comment, I tested this with a programatically created searchbar and it works as well.
I am adding multiple UITextFields to my alert controller, and I don't want that ugly black box around them. I know it's not the border property of the textField, because I have tried setting that and that influences the actual textField, not the box.
I have tried
textField.superview?.backgroundColor = UIColor.redColor()
textField.superview?.layer.borderColor = UIColor.redColor().CGColor
Setting the background Color works as expected, filling in the space between the textfield and the "black border" but setting the borderColor or borderWidth on superview.layer do nothing. Any ideas?
I ended up subclassing UIAlertController.
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
for field in textFields! as [UITextField] {
field.superview?.superview?.layer.borderWidth = 2
field.superview?.superview?.layer.borderColor = UIColor.whiteColor().CGColor
}
}