UISearchBar clear button colour change - ios

I've spent a lot of time in searching for a solution but couldn't find any which works and is efficient. As I understand we can't change tint colour of clear button as this property isn't available? The other solution is to change clear button image all together.
https://stackoverflow.com/a/50386999/10733471 this solution comes to the closest but problem with this is that it doesn't show clear button very first time you launch app and enter into search bar to type.
Can anyone suggest a working & efficient solution which doesn't involve using a new image? I'm looking for a solution which takes the default clear button image and reuses it after changing it's colour.

Add the following code to change the color of clear button in Search Bar
let imgClear = UIImage(named: "cross")
searchbar.setImage(imgClear, for: .clear, state: .normal)
This code is working on first time also I have checked in sample project it is working perfectly

Related

Image in Button for Xcode is showing only tint color on old version [duplicate]

So, I'm a relatively new coder and understand this may be a real simple fix but I can't seem to find how anywhere, just that people know it happens. It is also possible I've misunderstood some other core idea and that is why I can't seem to fix.
I've set up a UIKit button in my storyboard, added both an IBAction and IBOutlet for this button in my script (class? whatever the individual .swift files are called within a project), set the IBO to inherit from UIButton, all in the ViewController class. In the viewDidLoad function I have
button.setImage(UIImage (named: "logo"), for: .normal)
and another line of coder pertaining to a UILabel (everything is fine there). Below the viewDidLoad function I have an array and then the IBA with a little bit of code that shuffles the array and spits out 0 indexed spot onto the screen.
I've been trying to fix this for a few days now and assuming I've understood everything I've read, I've learned that UIImages are immutable (can't be changed) so that tells me that I need to fix this when declaring it in viewDidLoad. I've also learned that it being blue is default in the current swift/xcode state, and that it is a render mode issue, just turning that off will fix the problem. I can't for the life of me connect the last few dots and figure out how to actually tell Xcode to simply use the image I've provided it.
I'm looking for a code solution of course, but the knowledge of why it will work and any corrections/clarifications to what I think I've learned will be even more appreciated so I can help myself more in the future.
Thank you in advance.
-Cyre
Since you haven't specified, I'm assuming the button's "Type" is set to "System" in the storyboard (the default button type when you drag out a new UIButton in storyboards).
By default, system buttons take any image set on it and apply a template rendering mode to it, which makes the image render all non-transparent pixels as a flat color (e.g. the tint color of the button in this case, which is by default the system blue color that you're seeing).
UIImages by default have a renderingMode of automatic, which means the actual effective rendering mode the image takes on is determined by whatever is using the image (in this case, the UIButton).
You can, however, instantiate a UIImage with a renderingMode of alwaysOriginal so that it never is treated as a template image. There are a couple of ways to do this.
1. Programmatically
You can create a new image object with a new rendering mode in code by taking the image you're already creating:
UIImage(named: "logo")
and calling withRenderingMode(_:) on it to return to you a new UIImage object that you then set on your button:
let logoImage = UIImage(named: "logo")
let logoImageAlwaysOriginal = logoImage?.withRenderingMode(.alwaysOriginal)
button.setImage(logoImageAlwaysOriginal, for: .normal)
2. Asset Catalog
An easier way than going the programmatic route above is to just change the image's default rendering type in your asset catalog. Click on the image you want to change in your asset catalog ("logo" in this case), then go to the Attributes Inspector (keyboard shortcut: option+command+4), and change the "Render As" attribute to "Original Image". Now, whenever you use or get this image from the asset catalog (either in your storyboards or in code), the image will have the rendering mode of .alwaysOriginal.
You can either do any of the above options and keep the system button type, OR you can just change your button's type to "Custom" in the storyboard, as custom buttons do not apply a template rendering mode to their images by default. However, you lose some nice things when not using the system button type, like the text color no longer is taken from the button's tint color, and the button doesn't have a nice fade animation when unpressed.

Navigation Bar black line with Large title

Thanks for taking the time to read.
Firstly, let me say that I have tried to do my due diligence in searching for a solution to the problem, but to no avail, and it is stressing me out! So, if someone finds an answer could you please point me in the direction :)
The problem I am facing is to do with the black line appearing underneath the Navigation Bar. Now, I am very much aware of the setting a default image/shadow image property of the navigation bar to correct this, and as such, I created my own extension to implement it (shown below)
func hideHairline(_ state:Bool) {
if state {
self.shadowImage = UIImage()
self.setBackgroundImage(UIImage(), for: .any, barMetrics: .default)
}else{
self.setBackgroundImage(UINavigationBar.appearance().backgroundImage(for: UIBarMetrics.default), for:UIBarMetrics.default)
self.shadowImage = nil
}
}
However, something seems to be misbehaving, and I am getting a black line appearing underneath my navigation bar (see below)
Whats more strange, is that the simulator does not show this line on the same screen. The simulator is set to be pixel accurate. (as shown below)
I think it may have something to do with the way I am changing from a previous VC. I am changing from having the navigation bar hidden, to shown, and it is set to prefersLargeTitles. Now, if I set the navigation bar, not to use the large titles, the black line doesn't show. Also, if I push to the next view controller, and then pop back, the line is not there (on the pushed controller, or the newly presented popped)
At this point, I am mainly just wondering why this is happening? I mean, I must have done something wrong. I wrote a setup extension, just to keep the code away from the VC, probably isn't the best coding practice, but hey!
self.hideHairline(true)
self.titleTextAttributes = [NSAttributedStringKey.foregroundColor : Constants.navigationBarTextColor]
self.largeTitleTextAttributes = self.titleTextAttributes
self.barTintColor = Constants.navigationBar
self.tintColor = Constants.navigationBarTint
self.isTranslucent = false
self.backgroundColor = Constants.navigationBar
self.prefersLargeTitles = true
The Constants is a class that holds all of the static variables in my app, such as colo(u)rs. Have I just made some stupid mistake, or is there a bug with large titles?
If you need any further information, please, just ask :)
Thanks
So, after taking a break for the evening, I have found a solution. I am going to leave this post up, for anyone else that might encounter a similar problem in the future.
It is to do with the view of the UINavigationController itself. I found another stack overflow post that answered it (link here)
All I had to do was:
self.navigationController?.view.backgroundColor = .white
change the colo(u)r to whatever you need it to be.
Simple solution, and I cannot believe it took me so long to figure out.
All the best.

Swift UIButton - How to remove underline?

I have problem when in iOS settings is enabled this setting "Button Shapes"
It causing this underline in application (first picture with enabled setting, second without)
Any idea how to programatically or in storyboard disable it?
I tried attributed text but I get same result :(
I'm newbie in Swift.
Thanks for help!
It's not a problem. You should not make any attempt to counter any accessibility changes set by the user. They are there for a reason.
This is an answer by user4291543 from this question Remove underline on UIButton in iOS 7
[yourBtnHere setBackgroundImage:[[UIImage alloc] init] forState:UIControlStateNormal];
I found this answer works with SWFrameButton
And for all the others saying "Don't Do This", SWFrameButton is a very good example of when you would want to do this. I also think the OP's situation is a perfectly valid scenario as well...
I totally agree with #maddy's comment:
It's not a problem. You should not make any attempt to counter any accessibility changes set by the user. They are there for a reason.
But I did stumble on a way to accomplish the task at hand...
In addition to a UIButton, you'll also need to make a .png file that contains nothing (meaning the entire contents have an opacity of 0%). Go ahead and load that into your xcode project's assets.
Now go ahead and set the Button's Background to that image you just provided. (In my case, I called it clear) This will remove the underline from the button's text. However, now you can't see the boundaries of the button. This can be solved by changing the Background of the button's View. Go ahead and select any color for the View's Background property and now the background of the View visibly defines the button's boundaries. You're able to see this because your clear.png has an opacity of 0%.
see the Attributes inspector for UIButton here.
Rather than trying to defeat the underline by going to make a label perform some action via UITapGestureRecognizer, this allows you to still use a UIButton. Keeping inline with accessibility features to mark buttons for people that want to do that.
You could create a custom button class with a label (with clear color). If you set the text of this label instead it shouldn`t get an underline.
Are you sure you want to do that?
Apple added an accessibility feature to mark buttons for people that want to do that. Apple will probably reject your app because it defeats a system function meant to help the disabled.
I found the solution. All you have to do is set a picture as the background of the button. just pick a picture with the same color as the button you created.

Full customisation of UINavigationBar

I'm currently building an iOS Application for a client and have hit a pretty huge roadblock. I mean, I could write my own UINavigationBar and such but that would cause a lot of issues further down the road.
I have tried everything in my knowledge so far and have spent several hours searching for a solution (overriding the CALayer, using CoreGraphics and pretty much everything else ) and I get the same result. No matter how hard I try to remove the background of the UINavigationBar, it still shows a white background with slight translucency.
I need to have a lot of customisation on the navigation bar (I.E having a gradient going from "blackColor" to "clearColor" and I can't do that if the background of the Navigation Bar refuses to be completely transparent. I have tried copying all of the CALayers from the UINavigationBar layer to a subview I added and it just kept crashing, even when replacing the delegates and superlayer.
I really need help with this. One of the multiple effects I'm trying to achieve are below. (The blue rectangle is not the focus of the image, it's irrelevant.)
To get it completely transparent:
(UINavigationBar.appearance()).translucent = true
(UINavigationBar.appearance()).barTintColor = UIColor.clearColor()
(UINavigationBar.appearance()).backgroundColor = UIColor.clearColor()
(UINavigationBar.appearance()).setBackgroundImage(UIImage(), forBarMetrics: UIBarMetrics.Default)
(UINavigationBar.appearance()).shadowImage = UIImage()
EDIT:
Using iOS 8.3 looking like this:
Or am I missing something?
You are referring to the top Navbar with the back button and Save button right? I'm just confused as to what the blue box on the image is in reference too.
Anyways, this is an extremely hacky approach but could work:
Set the UINavigationBar's alpha to 0. The Back button and Save button will probably also disappear but you could just add labels to the View Controller at the top in the exact same place. The button's should still be functional even though they are "invisible" but the user will still think they are touching them.
Again, very hacky, but you are free to play with the top part of the View then. I'm sure there's a better way to do this but I'm not near a computer with XCode at the moment and can't test it out, and this fix may not even work but I thought I'd offer up a possible temporary solution.

iOS Tab Bar questions (Swift)

I have a couple questions about the iOS tab bar.
My first question is, is the image always tinted automatically? Say for example, I used an image that was colored red, is there a way to get it to show the red without tinting it? I guess what I am saying is, can you show the natural color?
My second question is, assuming the tinting is mandatory, how would I go about tinting the images in the tab bar that are not the currently selected image? I have the selected image tint figured out.
I tried changing the tint under, UIView.appearance() I believe and that worked, but when I selected a different tab, and then navigated back the color went back to the former grayish color.
If I am not being clear enough, let me know and I will explain more. I am using swift, so any examples you give would be great in swift! Thanks!
Say for example, I used an image that was colored red, is there a way to get it to show the red without tinting it?
What you want to do is to specify an image with rendering mode .AlwaysOriginal.
To govern both images, create the item with initWithTitle:image:selectedImage: and make them both .AlwaysOriginal.
(As you discovered, if you use a transparency mask and rely on the tintColor, you lose control of the tint color when unselected.)

Resources