UISearchBar Customization - ios

I'm trying to customize UISearchBar but I"m having a hard time with it.
This is what my searchbar looks like currently. What I want to be able to do is set a uiimage on the entire uisearchbar. I tried setSearchFieldBackgroundImage but it does not affect the text field part of the searchbar. How can I put an image in the white part? I also want to extend the white part to the edge to have equal margins on all sides.

for the image purpose u could use this one,dont forget to import Quartzcore framework
[searchbar setBackgroundImage:[UIImage imageNamed:#"base_200x50.png"]];
[searchbar setTranslucent:YES];
UITextField *txtSearchField = [searchbar valueForKey:#"_searchField"];
[txtSearchField setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"base_200x50.png"]]];
[txtSearchField setBorderStyle:UITextBorderStyleRoundedRect];
txtSearchField.layer.borderWidth = 8.0f;
txtSearchField.layer.cornerRadius = 10.0f;
txtSearchField.layer.borderColor = [UIColor clearColor].CGColor;
and to extend textfeild u can set frame of txtSearchField.

I hope this may help you:
Pattern image I used:
#IBOutlet weak var sbSearchBar: UISearchBar!
// if you wan to set background color for searchbar, except field
func setupSearchbarBackgroundImage() -> Void {
sbSearchBar.setBackgroundImage(UIImage(named: "pattern2"), for: UIBarPosition.any, barMetrics: UIBarMetrics.default)
}
Result:
func setupSearchbar() -> Void {
// if you wan to set background color for field only
if let textfield = sbSearchBar.value(forKey: "searchField") as? UITextField {
textfield.backgroundColor = UIColor(patternImage: UIImage(named: "pattern2")!)
}
}
Here is result:

Related

iOS 11 UISearchBar background color

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

How To Change UITextView Cursor Blink Color in Xcode

Hello people can anyone help us in how to change the cursor blink color of UITextView in Xcode using Swift language or from storyboard.
Swift 4, Xcode 9.1 Beta
I tried setting the tintColor of my UITextView in the interface builder but that didn't work for me. I don't know why, but setting the tintColor on my UITextView to one color, then resetting it to the color I really wanted worked for me...
myUITextView.tintColor = .anySystemColor
myUITextView.tintColor = .theColorYouReallyWant
For some reason that I don't know, I had to run a didChange method because tintColor on its own doesn't work.
BTW, I'm on Swift 5.
textView.tintColor = .white
textView.tintColorDidChange()
It works for me!
just change Tint Color
UITextView.appearance().tintColor = .black
Objective-C:
[[UITextView appearance] setTintColor:[UIColor blackColor]];
To do it in storyboard, do this
Set the Tint to your desired color.
I tried setting the tintColor of textView and textField in storyboard.
TextField cursor changed color, but textView didn't.
It helped me next:
let redTintColor: UIColor = UIColor.red
override func awakeFromNib() {
super.awakeFromNib()
textView.tintColor = redTintColor
}
or
let redTintColor: UIColor = UIColor.red
override func awakeFromNib() {
super.awakeFromNib()
textView.tintColor = redTintColor
textView.tintColorDidChange()
}
Just assign the tint color twice.
textView.tintColor = UIColor.black
textView.tintColor = UIColor.white
This works fine and looks better then double assign
DispatchQueue.main.async {
self.addressTextView.tintColor = UIColor.yourColor
}

Change Press Down Color of UITableView

When I tap or hold one of the cells in the UITableView the color of the cell becomes gray by default. I want it to be some other color. I looked everywhere in the storyboard and on stack overflow but could't find it. How do we do it.
Try to change it like this, which will be red for example:
let bgColorView = UIView()
bgColorView.backgroundColor = UIColor.redColor()
cell.selectedBackgroundView = bgColorView
This is an extension based to #evgeny-karkan answer
extension UITableViewCell {
func ChangePressDownColor(to Color: UIColor){
let bgColorView = UIView()
bgColorView.backgroundColor = Color
self.selectedBackgroundView = bgColorView
}
}
Usage:
cell.ChangePressDownColor(to: .red)
check the selection after selecting the cell, where it currently says default.
however, this is very limited number of selection.
if you want custom, you should do it programatically.
i.e./ cell.selectedBackgroundView = customView with color

UISearchBar custom corners

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

Adding Background Image into View Controller

I tried to use this code under in my app delegate in order to add a PNG image as a view controller's background :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[self window] setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"background.png"]]];
return YES;
}
but I have no luck with it... the view controller still has a white background. What's wrong with that code?
The accepted answer and Michael's answer will work, however, proper way is to use a UIImageView instead. It gives more control over resizing, scaling etc according to different screen sizes on devices. Here is the example;
First create a UIImage.
UIImage *backgroundImage = [UIImage imageNamed:#"iphone_skyline3.jpg"];
Second create a UIImageView. Set the frame size to the parent's (self) frame size. This is important as the frame size will vary on different devices. Stretching will occur depending on the image size. Next assign the image to the view.
UIImageView *backgroundImageView=[[UIImageView alloc]initWithFrame:self.view.frame];
backgroundImageView.image=backgroundImage;
Finally, to keep the image behind all controls do the following. It is important if you are setting the image as a background for your app.
[self.view insertSubview:backgroundImageView atIndex:0];
You need to set the background for your ViewController's view
In your ViewController init or viewDidLoad:
[self.view setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"background.png"]]];
Here is how it is in swift:
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor(patternImage: UIImage(named: "background.png"))
}
Swift 4 version of the #hadaytullah answer with some improvements in image adjustments:
override func viewDidLoad() {
super.viewDidLoad()
let backgroundImage = UIImage.init(named: "yourImageNameHere")
let backgroundImageView = UIImageView.init(frame: self.view.frame)
backgroundImageView.image = backgroundImage
backgroundImageView.contentMode = .scaleAspectFill
backgroundImageView.alpha = 0.1
self.view.insertSubview(backgroundImageView, at: 0)
}
You could also write extension to UIViewController to use in multiple places
extension UIViewController {
func setBackgroundImage(imageName: String) {
let backgroundImage = UIImage(named: imageName)
let backgroundImageView = UIImageView(frame: self.view.frame)
backgroundImageView.image = backgroundImage
self.view.insertSubview(backgroundImageView, at: 0)
}
}
In viewDidLoad, I use:
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"yourImageString.png"]];
Alternatively, if you want to do it in appDelegate, I think its possible to
[self.window setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"yourImageString.png"]]];
Then in viewDidLoad set background to [UIColor clearColor] ?
If your view controller is having tableView/collection view the below code will suitable for you.
- (void)viewDidLoad
{
[super viewDidLoad];
self.tableView.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"yourImage.png"]];
}
you may consider the following solution i use in swift 3.0 and tested in xcode 8
// init and image with your pattern image
var bgUIImage : UIImage = UIImage(named: "yourIamgeName")!
let myInsets : UIEdgeInsets = UIEdgeInsetsMake(0, 0, 0, 0)
bgUIImage = bgUIImage.resizableImage(withCapInsets: myInsets)
self.view.backgroundColor = UIColor.init(patternImage:bgUIImage)
the result will be the following image
You can do it from the storyboard.
Add UIImageView and just set your background image for the Image property in the Attribute Inspector.

Resources