I am customizing a UINavigationBar like so:
UIImage * img = [UIImage imageNamed:#"background.png"];
[[UINavigationBar appearance] setBackgroundImage:img forBarMetrics:UIBarMetricsDefault];
My original image background.png looks like this:
It has a flat color #4b0367
The resulting NavigationBar looks like this:
It has the color #311253 which is different from the original!
Apparently UIKit changes the color.
Note:
Setting tintColor had no effect.
Setting a transparent background image + a color is not an appropriate solution in my case.
Does anybody know how the underlying mechanism works?
How can I get the original image to appear correctly?
Related
All,
We have icon design from PhotoShop, It is Square transparent image with a Polygon inside which has a blue color. Based on some conditions i want to change the Polygon color but on the complete image color. Can we do this in code (Objective C)
I am attaching a Image in which the Only background "blue" color need to be changed based on the color we give. How can we achevie that
You can do this by rendering the image in UIImageRenderingModeAlwaysTemplate mode & after that set tintColor.
imageView.image = [imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[imageView setTintColor:[UIColor redColor]];
I have a UIToolbar in one of my VCs, it has 3 color buttons which changes the color of my drawing. Anyways I want to change the button's image when its selected. The images are shown below, the problem is apparently the button's "tintcolor" is messing with the original image.
If i set the "tintcolor" to red my active button looks like a bigger red circle, if its "clearcolor" it doesn't show. Any help would be much appreciated guys.
UIImage *image = [UIImage imageNamed:#"red-selected"];
[button setImage:image];
I even tried:
UIImage *image = [[UIImage imageNamed:#"red-selected"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
[btn setImage:#"red-selected.png" forState:UIControlStateNormal];
you can also do it in the interface builder - indicates a photo for selected mode.
pay attention the type of the photo- is it png?
try #"red-selected.png"/ #"red-selected.jpg"
I'm having trouble customising an UISegmentedControl: I've subclassed it I'm setting it's background for both the selected state and the unselected state like this:
#define kEdgeInsets UIEdgeInsetsMake(18, 18, 18, 18)
UIImage *grayImage = [[UIImage v_imageNamed:#"gray_rect"] resizableImageWithCapInsets:kEdgeInsets];
[self setBackgroundImage:grayImage
forState:UIControlStateNormal
barMetrics:UIBarMetricsDefault];
UIImage *greenImage = [[UIImage v_imageNamed:#"green_rect"] resizableImageWithCapInsets:kEdgeInsets];
[self setBackgroundImage:greenImage
forState:UIControlStateSelected
barMetrics:UIBarMetricsDefault];
[self setTintColor:[UIColor colorWithRed:0.506 green:0.514 blue:0.525 alpha:1.000]];
Where this are the PNGs I'm using
Now, when I execute this code, I get a weird shadow on the segmented control, which is not what we want. This is what the output looks like
Which is very weird, because there is no shadow on the original images, nor does UISegmentedControl add one (as far as I know).
Further checking, I noticed that if I removed the resizableImageWithCapInsets: call, the image looks distorted (as one should expect) but without the shadow.
Any ideas? because I'm literally going mad over this, since I don't have this problem when using resizableImageWithCapInsets: with UIButton
Thanks a lot!
I figured it out.
Turns out the segmented controller's frame is of 44pts height, and the background images was 75ptsx75pts. Since i've set the image's top and bottom inset to 18pts, the OS was taking the image's top and bottom 18pts and resizing it, ignoring the rest. Here is the fun part, since the image has a gradient, the rest of the image is ignored and it the control is colored like that.
In order to use images with vertical gradients you must use a base PNG with the exact same height as your control (http://useyourloaf.com/blog/2012/07/05/customizing-appearance-with-resizable-images.html)
This is what I did, resize the image to 44x44pts and change the insets to UIEdgeInsetsMake(0, 10, 0, 10) denoting that the image can't have to be resized vertically
If I do self.tabBar.tintColor = [UIColor whiteColor];
I manage to get the image of the selected tab bar white.
How do I get the image of the unselected tab bar black, or dark grey or red?
You can use something like this. The clue of this line of code is UIImageRenderingModeAlwaysOriginal. That means that the code is showing the original image. If your image is red, the icon will be red and if your image is blue, your icon will be blue.
Add this code in the first ViewController for every TabBarItem
- (void)viewDidLoad
{
[super viewDidLoad];
self.tabBarItem.image = [[UIImage imageNamed:#"yourImage.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
self.tabBarItem.selectedImage = [[UIImage imageNamed:#"yourImage.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
...
{
Now, you don't need your self.tabBar.tintColor = [UIColor whiteColor]; any more.
Rendering Modes by Apple Documentation:
UIImageRenderingModeAutomatic, // Use the default rendering mode for the context where the image is used
UIImageRenderingModeAlwaysOriginal, // Always draw the original image, without treating it as a template
UIImageRenderingModeAlwaysTemplate, // Always draw the image as a template image, ignoring its color information
Check this answer: stackoverflow.com/a/22766669/1381708
On my nav bar, I have a couple of rightBarButtonItems that have custom icons (the icon images are white, which worked well with the basic color scheme of iOS 6).
Under iOS 7, loading the images using initWithTitle (see code snippet 1) replaces the "white" color in the icon with the proper global tint (a specific color of dark blue in this case)
Code Snippet 1:
UIBarButtonItem *refreshButton = [[UIBarButtonItem alloc] initWithTitle:#"" style:(UIBarButtonItemStyle) UIBarButtonSystemItemCancel target:(self) action:#selector(refreshList)];
refreshButton.image = [UIImage imageNamed:#"RefreshIcon.png"];
However, I needed to use initWithCustomView to overcome a weird change in behavior that was causing the icons to move out of view. The basic idea was to specifically set the size of the icons. initWithCustomView solved the sizing problem, but does not display the button images with the global tint, they are displayed in the color of the image (white). Code Snippet 2 shows how I am creating the button with initWithCustomView.
Code Snippet 2:
CGRect frameCustomButton2 = CGRectMake(0.0, 0.0, 18.0, 18.0);
UIButton *customButton2 = [[UIButton alloc] initWithFrame:frameCustomButton2];
[customButton2 setBackgroundImage:iconRefreshButton forState:UIControlStateNormal];
UIBarButtonItem *barCustomButton2 =[[UIBarButtonItem alloc] initWithCustomView:customButton2 ];
barCustomButton2.image = iconRefreshButton;
[customButton2 addTarget:self action:#selector(refreshList) forControlEvents:UIControlEventTouchUpInside];
All of this code is of course in (void)viewDidLoad. I have tried things like:
barCustomButton2.tintColor = [UIColor blackColor]; //doesn't work
or
[barButtonAppearance setTintColor:[UIColor blackColor]]; // doesn't work
and they do not override the white color of the image. It is almost as if the creation of the custom view takes place after the view looks at the global tint color?
How can I ensure the button icon takes on the global tint?
Thanks!
Just wanted to get this into a root comment to give better context to the "answer" checkmark, and give better formatting.
I was able to figure this one out! You can tell the image to always render as template, which will force it to take on the global tint color.
UIImage *iconRefreshButton = [UIImage imageNamed:#"MyIconFilename.png"];
iconRefreshButton = [iconRefreshButton imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
The default, if you don't set it, is "UIImageRenderingModeAutomatic" which means it will render as a template or original image based on context.
You'll either have to work around the issue you were having with the first code snippet, or you'll have to create a UIButton subclass that uses its image as a mask to show the tint color in drawRect:.
I'd recommend the first approach.