UINavigationBar : Add SearchBar as TitleView - ios

I want to add uisearchbar in place of title of controller.
I am facing 2 problems currently.
1)
I do not know from where this gray background is coming. Please check this picture.
2) I need this searchbar in other inner screens also. But when I push another controller this searchbar is removed.
Here is my code :
// Seachbar Container View
let searchBarContainer = ERView(frame: CGRectMake(0,0,280,44))
searchBarContainer.autoresizingMask = [.FlexibleWidth]
searchBarContainer.backgroundColor = UIColor.clearColor()
// Search Bar
let searchBar = ERSearchBar(frame: searchBarContainer.bounds)
searchBarContainer.addSubview(searchBar)
// Add View as Title View in Navigation Bar
self.navigationController!.navigationBar.topItem?.titleView = searchBarContainer
Here is Code of my UISearchBar Class
func commonInit() -> Void {
// Update UI
if let searchField = self.valueForKey("searchField") as? UITextField{
// To change background color
searchField.backgroundColor = UIColor.appNavigationBarDarkRedColor()
// Tint Color
if let leftViewRef = searchField.leftView {
leftViewRef.tintColor = UIColor.whiteColor()
}else if let imgLeftView = searchField.leftView as? UIImageView{
imgLeftView.tintColor = UIColor.whiteColor()
}
// Font Color
searchField.font = UIFont.robotoRegularFont(WithSize: 14.0)
// Text Color
searchField.textColor = UIColor.whiteColor()
// PlaceHolder Attributes
searchField.attributedPlaceholder = NSAttributedString(string: "Search", attributes: [NSForegroundColorAttributeName:UIColor.whiteColor()])
}
self.setImage(UIImage(named: "ic_search_white"), forSearchBarIcon: UISearchBarIcon.Search, state: UIControlState.Normal)
// To change placeholder text color
}
Please someone help me here.

For 1) Set the searchBarStyle property to minimal. This will provides no default background color in UIsearchBar.
2)I'm not quite sure what'd you mean by "inner screen". But if what you want is a Search Bar that can work across different view controllers, UISearchController is the one you're looking for.
You can fine the Apple sample code here

Related

Bar Button tint color in iOS 13

In iOS 13, they have changed the way that the nav bar colors operate. Now they use UINavigationBarAppearance along with UIBarButtonItemAppearance to customize the nav bar, along with standardAppearance & scrollEdgeAppearance.
I'm looking for a way to have different nav bar tint colors for standardAppearance & scrollEdgeAppearance. Or the ability to change bar button icon colors for each appearance.
//set the standard nav bar appearance
let navBarAppearance = UINavigationBarAppearance()
navBarAppearance.configureWithOpaqueBackground()
navBarAppearance.titleTextAttributes = [.foregroundColor: UIColor.white]
navBarAppearance.largeTitleTextAttributes = [.foregroundColor: UIColor.white]
navBarAppearance.backgroundColor = UIColor.mainAppColorForNavBar
//set bar button appearance
let buttonAppearance = UIBarButtonItemAppearance()
buttonAppearance.normal.titleTextAttributes = [.foregroundColor : UIColor.white]
navBarAppearance.buttonAppearance = buttonAppearance
UINavigationBar.appearance(whenContainedInInstancesOf: [UINavigationController.self]).standardAppearance = navBarAppearance
//set the scroll edge nav bar appearance
let scrollNavBarAppearance = UINavigationBarAppearance()
scrollNavBarAppearance.configureWithOpaqueBackground()
scrollNavBarAppearance.titleTextAttributes = [.foregroundColor: UIColor.label]
scrollNavBarAppearance.largeTitleTextAttributes = [.foregroundColor: UIColor.label]
//set bar button appearance
let scrollButtonAppearance = UIBarButtonItemAppearance()
scrollButtonAppearance.normal.titleTextAttributes = [.foregroundColor : UIColor.label]
scrollNavBarAppearance.buttonAppearance = scrollButtonAppearance
UINavigationBar.appearance(whenContainedInInstancesOf: [UINavigationController.self]).scrollEdgeAppearance = scrollNavBarAppearance
This will set the nav bar tint color but does not distinguish between standardAppearance & scrollEdgeAppearance.
UINavigationBar.appearance().tintColor = UIColor.white
currently in scrollEdgeAppearance (looks the way I want, no changes needed)
currently in standardAppearance (the button is lost because it's the same color as the background, I want to change the icon color to white in standardAppearance )
Any help is appreciated.
Thanks,
I ran into a similar issue for the back button and solved it with setting an image with a different rendering mode for each appearance. This avoids a tintColor being applied.
// demo image
let image = UIImage(systemName: "ellipsis.circle")!
// image with .alwaysOriginal rendering mode to avoid tintColor application
let imageForNavBarAppearance = image
.withTintColor(.black)
.withRenderingMode(.alwaysOriginal)
let imageForScrollNavBarAppearance = image
.withTintColor(.green)
.withRenderingMode(.alwaysOriginal)
// your UINavigationBarAppearance instances
navBarAppearance.setBackIndicatorImage(imageForNavBarAppearance, transitionMaskImage: imageForNavBarAppearance)
scrollNavBarAppearance.setBackIndicatorImage(imageForScrollNavBarAppearance, transitionMaskImage: imageForScrollNavBarAppearance)
This solves it for back buttons only.
There are two other options to set background images for bar item appearances.
UINavigationBarAppearance.buttonAppearance
The appearance configuration with the background image would be applied to all bar items.
This should be fine, since you only have one bar item.
UINavigationBarAppearance.doneButtonAppearance
If you'd create a done-style bar item for your top-right "+" symbol, this appearance configuration should apply.
let ap = UIBarButtonItemAppearance()
ap.normal.backgroundImage = image.withTintColor(.black).withRenderingMode(.alwaysOriginal)
let scrollAp = UIBarButtonItemAppearance()
scrollAp.normal.backgroundImage = image.withTintColor(.green).withRenderingMode(.alwaysOriginal)
// apply to all bar items
navBarAppearance.buttonAppearance = ap
scrollNavBarAppearance.buttonAppearance = scrollAp
// or apply to done buttons
navBarAppearance.doneButtonAppearance = ap
scrollNavBarAppearance.doneButtonAppearance = scrollAp
After playing around with iOS 13 UINavigationBarAppearance , UIBarButtonItemAppearance etc. I realised that setting a color to navigationBar.tintColor directly apparenty overrides any UIBarButtonItemAppearance configurations.
So here is my workaround:
Given that your UIViewController most likely uses an UICollectionView, UITableView, UIScrollView use it’s UIScrollViewDelegate to get scroll updates. Also possible via KVO:
private func observeScrollView() {
self.observer = scrollView.observe(
\UIScrollView.contentOffset,
options: .new
) { [weak self] scrollView, change in
guard let offsetY = change.newValue?.y else { return }
self?.handleScroll(offsetY)
}
}
Now you need to calculate if your LargeTitles are still showing. You can use navigationController?.navigationBar.frame.maxY to access it’s height.
private func handleScroll(_ offsetY: CGFloat) {
let offsetY = -offsetY
let threshold: CGFloat = navigationController?.navigationBar.frame.maxY ?? 88
let largeTitlesVisible = offsetY > threshold
self.largeTitlesVisible = largeTitlesVisible
}
Use property observers to catch toggles.
private var largeTitlesVisible: Bool = true {
didSet {
if oldValue != largeTitlesVisible {
updateNavbar(tranparent: largeTitlesVisible)
}
}
}
Now actually change the navbars appearance:
func updateNavbar(transparent: Bool) {
// overrides UIBarButtonItemAppearance, UINavigationBarAppearance configurations ...
navigationController.navigationBar.tintColor = transparent ? UIColor.clear : UIColor.systemGreen
}

Customize the searchController of navigationItem , but doesn't work with iOS 11

I have searched the similar question UISearchController iOS 11 customizationbut al the methods in the comments couldn't help me out.So I want to ask it again.
I used the following codes to set the appearance of the searchBar.
Extension the UISearchBr to get the textField and placeHolderLabel:
extension UISearchBar{
var textField: UITextField?{
if let textField = self.value(forKey: "searchField") as? UITextField {
return textField
}
return nil
}
var placehloderLabel:UILabel?{
if let placeholderLabel = textField?.value(forKey: "placeholderLabel") as? UILabel{
return placeholderLabel
}
return nil
}
}
Customize a subclass of UISearchController:
class CustomSearchController:UISearchController{
override init(searchResultsController: UIViewController?) {
super.init(searchResultsController: searchResultsController)
self.definesPresentationContext = true
self.dimsBackgroundDuringPresentation = false
self.hidesNavigationBarDuringPresentation = true
self.searchBar.searchBarStyle = .minimal
self.searchBar.placeholder = "搜索歌单内歌曲"
self.searchBar.textField?.textColor = UIColor.white
self.searchBar.placehloderLabel?.textColor = .white
self.searchBar.placehloderLabel?.font = UIFont.systemFont(ofSize: 15)
}
Set prefersLargeTitles UINavigationBar.appearance().prefersLargeTitles = true
If navigationItem.searchController = searchController and the result is as follows (the appearance of the searchBar DOESN'T make change):
But if I set navigationItem.titleView = searchController.searchBar,it makes:
Does the iOS 11 permit developers to change the searchBar's
appearance?If yes,I wonder how to customize it ?Any
point is appreciated.Thanks!
Working with color and UINavigationItem's search controller
This code is in the AppDelegate class.
UISearchBar.appearance().tintColor = UIColor(named: "Button") // using this to set the text color of the 'Cancel' button since the search bar ignores the global tint color property for some reason
if #available(iOS 11.0, *) {
// Search bar placeholder text color
UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).attributedPlaceholder = NSAttributedString(string: "Search", attributes: [NSForegroundColorAttributeName: UIColor.white])
// Search bar text color
UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).defaultTextAttributes = [NSForegroundColorAttributeName: UIColor.red]
// Insertion cursor color
UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).tintColor = UIColor.red
} else {
// Fallback on earlier versions
}
// Search bar clear icon
UISearchBar.appearance().setImage(UIImage(named: "clear"), for: .clear, state: .normal)

Changing the text color of a navigation bar title when "prefersLargeTitles" is set to true

I have a requirement in which I have to use a UINavigationBar with a red large title.
Currently, I have the following code:
func prepareNavigationController() {
let navController = UINavigationController(rootViewController: self)
navController.navigationBar.prefersLargeTitles = true
navigationItem.searchController = UISearchController(searchResultsController: nil)
navigationItem.hidesSearchBarWhenScrolling = false
navController.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor.rawValue: UIColor.red]
}
But it's not actually tinting the title label to red. This is the result:
But changing prefersLargeTitles to false does the right thing, and my title is red.
navController.navigationBar.prefersLargeTitles = false
I am not entirely sure if this is a bug since at the time of this writing we are still in the first beta, or if this is intentional behavior, mostly because I haven't any of Apple's apps color the large titles before. Is there any way to actually get the large title to have any color I want?
There is a new UINavigationBar property "largeTitleTextAttribute" that should help with this.
largeTitleTextAttribute
Here is a sample code you can add to your view controllers viewDidLoad method
navigationController?.navigationBar.largeTitleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.blue]
Here is a sample code and screenshot without the largeTitleTextAttributes set, but the barStyle is set to .black
navigationController?.navigationBar.barStyle = .black
Here is a screenshot without the largeTitleTextAttributes set, but the barStyle is set to .default
navigationController?.navigationBar.barStyle = .default
The way you do this in iOS 13 has changed, you now use UINavigationBarAppearance class like this…
let appearance = UINavigationBarAppearance(idiom: .phone)
appearance.largeTitleTextAttributes = [.foregroundColor: UIColor.systemRed]
appearance.titleTextAttributes = [.foregroundColor: UIColor.systemRed]
appearance.backgroundColor = .white
navigationItem.standardAppearance = appearance
navigationItem.scrollEdgeAppearance = appearance
Not sure if it's a bug in beta 1 & 2, but here is a way to set the color. It's a bit of a "hacky" workaround, but it should work until Apple fixes this. In both the Objective-C and Swift version, this code goes in the viewDidAppear: method.
Objective-C:
dispatch_async(dispatch_get_main_queue(), ^{
for (UIView *view in self.navigationController.navigationBar.subviews) {
NSArray <__kindof UIView *> *subviews = view.subviews;
if (subviews.count > 0) {
UILabel *label = subviews[0];
if (label.class == [UILabel class]) {
[label setTextColor:[UIColor redColor]];
}
}
}
});
Swift:
DispatchQueue.main.async {
for view in self.navigationController?.navigationBar.subviews ?? [] {
let subviews = view.subviews
if subviews.count > 0, let label = subviews[0] as? UILabel {
label.textColor = UIColor.red
} } }
If using storyboard, just change "Large Title Text Attributes" Title Color at Navigation Bar Attribute Inspector:
Here's the working code to use large titles and sets the text color of small and large titles to white, both on iOS11+ and on older iOS versions.
// Will apply to versions before iOS 11
navigationController?.navigationBar.titleTextAttributes = [
NSAttributedStringKey.foregroundColor: UIColor.white
]
if #available(iOS 11.0, *) {
navigationController?.navigationBar.prefersLargeTitles = true
navigationController?.navigationBar.largeTitleTextAttributes = [
NSAttributedStringKey.foregroundColor: UIColor.white
]
}
(There used to be a bug in Xcode, but it now appears to be fixed)

How to change UIDocumentInteractionController Done button text and background color

How to change the background color and text color of done button? Is there a way that I can change the navigationbar color and navigation bar title color and bottom bar color also? Attached screenshot for reference:
I solved it. Here is the code working for me perfectly:
func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {
UINavigationBar.appearance().barTintColor = Colors.redColor()
UINavigationBar.appearance().tintColor = UIColor.white
UINavigationBar.appearance().titleTextAttributes = [NSForegroundColorAttributeName : UIColor.white, NSFontAttributeName: UIFont.systemFont(ofSize: 14, weight: UIFontWeightBold)]
return self
}
It's a little hacky as its relying on the fact that QLPreviewController is the class implementing the UIDocumentInteractionController but something like this is the least intrusive solution. Do it before you display the UIDocumentInteractionController
import QuickLook
UIBarButtonItem.appearance(whenContainedInInstancesOf [QLPreviewController.self]).tintColor = UIColor.black
I have a idear to change the bar color:
let allNavigationBar = UINavigationBar.appearance()
allNavigationBar.barTintColor = UIColor.red // change the bar background color
allNavigationBar.tintColor = UIColor.black // change the Done button's tintColor
let alloolbar = UIToolbar.appearance()
allToolbar.barTintColor = UIColor.red // dones't work, try backgroundImage
allToolbar.backgroundColor = UIColor.blue // dones't work
allToolbar.tintColor = UIColor.brown // change the toolbar's item tint color
but this method has a great effect,all your UINavigationBarand UIToolBar will make that change.
Hope anyone else can give a better solusion.
You can change the tint color of the window temporally.
func presentDocument() {
//present the controller here
self.appDelegate.window.tintColor = UIColor.red
}
Then change it back later:
func documentInteractionControllerDidEndPreview(documentInteractionController) { //replace parameter with your uidocumentviewinteractioncontroller
self.appDelegate.window.tintColor = UIColor.white
}
#Dee. I guess you have asked this part in one of your other question. In that case you were not able to show that preview controller. In that question suggested answer is to return "self" from that delegate method. If you implement that correctly then your preview will use same navigation bar colour as its parent controller is using. I mean if you have opened UIDocumentInteractionController directly from some ViewController then UIDocumentInteractionController will use its parent viewController's navigation bar colour. This may help you to change Done button colour
Try this : (You need to implement UIDocumentInteractionControllerDelegate)
func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {
return self.navigationController ?? self
}
let QLNavAppearance = UINavigationBar.appearance(whenContainedInInstancesOf: [QLPreviewController.self])
QLNavAppearance.tintColor = UIColor.red // some
QLNavAppearance.barTintColor = UIColor.red // some
QLNavAppearance.backgroundColor = UIColor.red // some

How to change the color of the UISearchBar Icon?

I don't know how to modify the original searchIcon's color.
The searchIcon is located in the leftView of the searchTextField. Since this is accessible we can easily set the tintColor for the view. The tintColor is also used for the searchIcon.
So in your code you can change the search icon to white with the following code:
searchBar.searchTextField.leftView?.tintColor = .white
Best solution I found was here
Changing the color of the icons in a UItextField inside a UISearchBar
(This solution uses the original UISearchBar's icon, no need to supply your own graphical asset)
Converted to Swift (Swift 3):
if let textFieldInsideSearchBar = self.searchBar.value(forKey: "searchField") as? UITextField,
let glassIconView = textFieldInsideSearchBar.leftView as? UIImageView {
//Magnifying glass
glassIconView.image = glassIconView.image?.withRenderingMode(.alwaysTemplate)
glassIconView.tintColor = .whiteColor
}
You can use a custom image of a white search icon, as the search bar will not modify your supplied image. To set a custom image, use this method. (Link to documentation.)
- (void)setImage:(UIImage *)iconImage
forSearchBarIcon:(UISearchBarIcon)icon
state:(UIControlState)state;
Example Code:
[searchBar setImage:[UIImage imageNamed:#"SearchIcon"]
forSearchBarIcon:UISearchBarIconSearch
state:UIControlStateNormal];
In Swift:
searchBar.setImage(UIImage(named: "SearchIcon"), for: .search, state: .normal)
This soultion worked for me on Xcode 8.2.1 in Swift 3.0. :
extension UISearchBar
{
func setPlaceholderTextColorTo(color: UIColor)
{
let textFieldInsideSearchBar = self.value(forKey: "searchField") as? UITextField
textFieldInsideSearchBar?.textColor = color
let textFieldInsideSearchBarLabel = textFieldInsideSearchBar!.value(forKey: "placeholderLabel") as? UILabel
textFieldInsideSearchBarLabel?.textColor = color
}
func setMagnifyingGlassColorTo(color: UIColor)
{
let textFieldInsideSearchBar = self.value(forKey: "searchField") as? UITextField
let glassIconView = textFieldInsideSearchBar?.leftView as? UIImageView
glassIconView?.image = glassIconView?.image?.withRenderingMode(.alwaysTemplate)
glassIconView?.tintColor = color
}
}
Usage example:
searchController.searchBar.setPlaceholderTextColorTo(color: mainColor)
searchController.searchBar.setMagnifyingGlassColorTo(color: mainColor)
Swift-3:
extension UISearchBar
{
func setMagnifyingGlassColorTo(color: UIColor)
{
// Search Icon
let textFieldInsideSearchBar = self.value(forKey: "searchField") as? UITextField
let glassIconView = textFieldInsideSearchBar?.leftView as? UIImageView
glassIconView?.image = glassIconView?.image?.withRenderingMode(.alwaysTemplate)
glassIconView?.tintColor = color
}
func setClearButtonColorTo(color: UIColor)
{
// Clear Button
let textFieldInsideSearchBar = self.value(forKey: "searchField") as? UITextField
let crossIconView = textFieldInsideSearchBar?.value(forKey: "clearButton") as? UIButton
crossIconView?.setImage(crossIconView?.currentImage?.withRenderingMode(.alwaysTemplate), for: .normal)
crossIconView?.tintColor = color
}
func setPlaceholderTextColorTo(color: UIColor)
{
let textFieldInsideSearchBar = self.value(forKey: "searchField") as? UITextField
textFieldInsideSearchBar?.textColor = color
let textFieldInsideSearchBarLabel = textFieldInsideSearchBar!.value(forKey: "placeholderLabel") as? UILabel
textFieldInsideSearchBarLabel?.textColor = color
}
}
Call these extension method like this:
searchBarTextField.setMagnifyingGlassColorTo(color: yourColor)
searchBarTextField.setClearButtonColorTo(color: yourColor)
searchBarTextField.setPlaceholderTextColorTo(color: yourColor)
For just changing the color of the search icon, without altering the actual icon in Swift 3:
if let textField = self.searchBar.value(forKey: "searchField") as? UITextField,
let iconView = textField.leftView as? UIImageView {
iconView.image = iconView.image?.withRenderingMode(UIImageRenderingMode.alwaysTemplate)
iconView.tintColor = UIColor.red
}
Creates a result like so:
As per Federica's anwser....To do this in swift
var image: UIImage = UIImage(named: "search")!
self.searchBar.setImage(image, forSearchBarIcon: UISearchBarIcon.Search, state: UIControlState.Normal)
A solution for those using interface builder. You can add a User Defined Runtime Attribute to the UISearchBar:
searchField.leftView.tintColor of type Color
You can select the desired color of the icon, can be selected from your Color Assets library to support different colors for both light and dark mode.
Since iOS 13, we now have access to many standard system icons via SF Symbols. Also, if you want to have a unified colour scheme for your search bars so that they all look the same without having to duplicate code, you can use the Appearance workflow to change them all at once. For example:
let image = UIImage(systemName: "magnifyingglass")?.withTintColor(.white, renderingMode: .alwaysOriginal)
UISearchBar.appearance().setImage(image, for: .search, state: .normal)
This code sets all search bars in the app to use the standard magnifying glass icon, in white. You can use similar code to change the 'clear' button icon, the bookmark icon and the results list icon. You just need to change .search to the appropriate enumeration value and find the system name of the appropriate icon (which you can get from the free SF System app).
Another method that uses Appearance would be to set the tint colour of all views contained within a search view, though this may have unwanted effects in some cases (i.e. changing the colour of the text cursor):
UIView.appearance(whenContainedInInstancesOf: [UISearchBar.self]).tintColor = .yellow
This will make the left icon and the text cursor yellow, though annoyingly not the 'clear' button for some reason. I prefer not to use this method as it may not be future-proof; Apple has a habit of changing things internally that can cause unexpected changes if you don't use their approved methods.
Following on from some of the answers here
If you would like to see and make the changes in storyboard first subclass UISearch bar and do as above.
However add the changes in a #IBInspectable variable and not forgetting the #IBDesignable at the top of the class and setting the searchbar subclass in the "Identity inspector"
I have added the full working subclass and code below for swift 3.0
Here you will be able to change the placeholder text, search text and magnifying glass
import UIKit
#IBDesignable
class CustomSearchBar: UISearchBar {
#IBInspectable var placeholderColor: UIColor? {
didSet {
let textFieldInsideSearchBar = self.value(forKey: "searchField") as? UITextField
let textFieldInsideSearchBarLabel = textFieldInsideSearchBar!.value(forKey: "placeholderLabel") as? UILabel
textFieldInsideSearchBarLabel?.textColor = placeholderColor
}
}
#IBInspectable var textColor: UIColor? {
didSet {
let textFieldInsideSearchBar = self.value(forKey: "searchField") as? UITextField
textFieldInsideSearchBar?.textColor = textColor
}
}
#IBInspectable var magnifyingGlassColor: UIColor? {
didSet {
if let textFieldInsideSearchBar = self.value(forKey: "searchField") as? UITextField,
let glassIconView = textFieldInsideSearchBar.leftView as? UIImageView {
//Magnifying glass
glassIconView.image = glassIconView.image?.withRenderingMode(UIImageRenderingMode.alwaysTemplate)
glassIconView.tintColor = magnifyingGlassColor
} }
}
}
Make sure that when you use the setImage API, pass an image with rendering mode of UIImageRenderingModeAlwaysTemplate. For example:
[self.searchBar setImage:[[UIImage imageNamed: #"icon-search"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] forSearchBarIcon:UISearchBarIconSearch state:UIControlStateNormal];
There are no adequate reasons to set your own custom image just for changing icon tint color. Don't forget about perfomance. And retrieving a value by a raw string key doesn't garantee that other coders can mistype usually calling app crashes. We're not perfect.
How about UISearchBar instance's property searchTextField (UISearchTextField)?
if let thatMysteriousLoop = yourSearchBar.searchTextField.leftView as? UIImageView {
thatMysteriousLoop.tintColor = anyColorYouWannaSet // <-- Voilà!
}
For swift 3
searchBar.setImage(UIImage(named: "location-icon-black"), for: .search, state: .normal)
My solution:
searchBar = UISearchBar()
searchBar.searchBarStyle = .minimal
searchBar.setTextColor(.white)
let textField = self.searchBar.getTextField()
let glassIconView = textField?.leftView as? UIImageView
glassIconView?.image = glassIconView?.image?.withRenderingMode(.alwaysTemplate)
glassIconView?.tintColor = .white
searchBar.showsCancelButton = true
extension UISearchBar {
func getTextField() -> UITextField? {
return self.value(forKey: "searchField") as? UITextField
}
func setTextColor(_ color: UIColor) {
let textField = getTextField()
textField?.textColor = color
}
}
I know it is an old post but since there is a Xamarin Bug on the dark mode and I was struggling for hours, I thought I share my pretty easy solution.
iOS- custom Renderer.
[assembly:ExportRenderer(typeof(SearchBar),typeof(YourProjectSearchbarRenderer))]
public class YourProjectSearchbarRenderer : SearchBarRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<SearchBar> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
// iOS >13 -> Xamarin bug on darkmode,
// just shows the light icon...
this.Control.SetImageforSearchBarIcon(UIImage.FromFile("AddAnSearchIcon.ico"), UISearchBarIcon.Search, UIControlState.Normal);
}
}
}
if(IOS_7) {
self.searchBar.searchBarStyle = UISearchBarStyleMinimal;
self.searchBar.backgroundImage = [UIImage imageWithColor:[UIColor redColor] cornerRadius:5.0f];
}

Resources