UIButton with transparent image background not drawing transparent - ios

I have run into a strange issue. I have a UIButton with UIButtonTypeCustom.
For it's background image, I am using a transparent image. The issue is that the transparency on the actual image doesn't seem to be correct. The odd thing is that it is in fact transparent, because the background shows correctly behind the button.
Below is an example of what the button looks like (left) and what the button should look like (right). I took a screenshot and overlaid the image on the background in Photoshop, and the background shows correctly inside the image, while in the actual button on the left it does not. Noticeably, the glow is more intense on the left UIButton vs. the actual image when inserted onto the background.
Here's the image I am using to show that it does in fact have transparency:
Here's my code:
UIButton *nextButton = [UIButton buttonWithType:UIButtonTypeCustom];
nextButton.backgroundColor = [UIColor clearColor];
nextButton.frame = CGRectMake(0, 0, 30, 30);
[nextButton setBackgroundImage:[[UIImage imageNamed:#"ButtonBackground.png"] stretchableImageWithLeftCapWidth:5 topCapHeight:5] forState:UIControlStateNormal];
forState:UIControlStateHighlighted];
[self addSubview:nextButton];
I have used the exact same image elsewhere to draw with and had no issue with transparency.
UPDATE: Adding other transparent images similarly increases the intensity of the alpha. While they're transparent, they seem darker and therefore less transparent. Again, works perfect elsewhere.
UPDATE 2: Even worse, I just created a new project with the exact same image dragged from the other project, created a button and had no issues with the button displaying correctly. How incredibly annoying!

You shouldn't have to set the background color for it to be transparent. Also, try removing the stretchable call on the image.
Also, you should be setting the image, not the background image.
If none of that helps, then Apple may just be improperly rendering your image. Try creating a CALayer and set its contents to your image and see if that works properly.

try this
UIButton *nextButton = [UIButton buttonWithType:UIButtonTypeCustom];
nextButton.frame = CGRectMake(0, 0, 30, 30);
nextButton.alpha=0.5f;
[nextButton setBackgroundColor:[UIColor clearColor]];
[nextButton setOpaque:NO];
[nextButton setBackgroundImage:[UIImage imageNamed:#"ButtonBackground.png"]
forState:UIControlStateNormal];

Related

imageWithRenderingMode doesn't work with setImageWithUrl (for tintColor)

I can tint a UIImage in a UIImageView using :
imageView = [[UIImageView alloc]initWithImage:[myImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]];
imageView.tintColor = [UIColor redColor];
But when the image is initialized with AFNetworking's setImageWithUrl :
imageView = [imageView setImageWithUrl:url];
imageView.image = [imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
imageView.tintColor = [UIColor redColor];
This has no effect, the image is displayed with original colors.
Tested on iOS 7+.
Your code has no effect because you are assigning the image to be fetched from the remote URL, which takes time and thus happens later - after your code has finished. Thus, this line does nothing:
imageView.image = [imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
...because, at the time it runs, imageView.image is still nil.
Instead, use a networking command with a completion handler, and don't change the image rendering mode until the completion handler. In particular, what I would do is: First, download the image. Now (in the completion handler) derive the template image and assign it to the image view.
EDIT:
Another problem, based on your later comments, is that you seem not to understand what an image view is. It holds one image - the most recently assigned image. So your code is now behaving exactly as I would expect - the image view is displaying the template image, because that is the last image you assigned to it.
imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate colors the non-transparent parts of the original image the tint color and that's all - and that is exactly what you are now seeing, so your code is working.
If someone still reaches this question, my suggestion would be to use UIButton instead of UIImageView. Import "UIButton+AFNetworking.h" and setUserInteractionEnabled as "FALSE" for UIButton to make it behave like a UIImageView.
The reason behind this is to use "setTintColor" of a system UIButton which functions likely in the same way as imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate
Check below code:
UIButton *myButton = [UIButton buttonWithType:UIButtonTypeSystem]; // to use tint color property
[myButton setFrame:CGRectMake(xPos, yPos, btnWidth, btnHeight)];
[myButton setTintColor:[UIColor lightGrayColor]];
[myButton setImageForState:UIControlStateNormal withURL:imageURL placeholderImage:[UIImage imageNamed:#"placeholder.png"]];

Custom UIButton iOS App

I'm developing an iOS app and i have to insert an UIButton.
I want to customize this button and i'd like to have a button like this:
My code is this, but i'm not able to make rounded corners:
_topImagesScrollViewButton = [UIButton buttonWithType:UIButtonTypeCustom];
_topImagesScrollViewButton.frame = CGRectMake(screenWidth/2-25, topBarHeight+paddHeight, 37 , 37);
_topImagesScrollViewButton.backgroundColor = [UIColor colorWithRed:red_middle green:green_middle blue:blue_middle alpha:alpha_middle];
[_topImagesScrollViewButton setTitle:#"Top" forState:UIControlStateNormal];
[_topImagesScrollViewButton setTitleColor:[UIColor colorWithRed:red_text green:green_text blue:blue_text alpha:alpha_text] forState:UIControlStateNormal];forState:UIControlStateNormal];
[_topImagesScrollViewButton addTarget:self action:#selector(topImagesScrollVieButtonTapped) forControlEvents:UIControlEventTouchUpInside];
How can i do?
I would use the above image to set the image of the button, instead of drawing the shape:
[_topImagesScrollViewButton setImage:#"yourimagename.png" forState:UIControlStateNormal];
This is how to make UIView with rounded corners: IOS: create a UIImage or UIImageView with rounded corners
And what about text color... everything seems to be ok. Maybe it doesn't work because you set title color twice for the same state. And the second from the bottom string of your code is excess.

UIImage PNG Opacity adjustment

I have created a custom button using a .png image that has transparency. However, when I implement it as a UIImage, the transparency is lost. Here's the code that I'm using:
- (void)setMyCustomBackButton;
{
UIImage *backButtonImage = [UIImage imageNamed:#"Back Button.png"];
UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
[backButton setBackgroundImage:backButtonImage forState:UIControlStateNormal];
[backButton addTarget:self action:#selector(popCurrentViewController) forControlEvents:UIControlEventTouchUpInside];
backButton.frame = CGRectMake(0, 0, backButtonImage.size.width, backButtonImage.size.height);
UIView *backButtonView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 63, 33)];
backButtonView.bounds = CGRectOffset(backButtonView.bounds, -12, -2);
[backButtonView addSubview:backButton];
UIBarButtonItem *finalBackButton = [[UIBarButtonItem alloc] initWithCustomView:backButtonView];
self.navigationItem.leftBarButtonItem = finalBackButton;
}
Is there a UIImage property for transparency? Does it have to do with opacity?
If you're creating the PNG in an image editing software, please make sure you've encoded the transparency while creating the image. Sometimes some image editors have an option for 'saving transparency' that's unchecked by default, when you're exporting something as a PNG.
Other than that, any transparency on a PNG will show up on a UIButtonTypeCustom. You don't need to do anything special to preserve transparency on a UIImage that's loading up a PNG.
Before you use the image in the code, please open it in Preview to make sure the transparency is present.
Oh and to answer your other question, UIImage does not have any properties relating to transparency. The closest thing you have is the alpha property for a UIView but even that simply changes the overall opacity of your UIView.
EDIT: Missed this the first time I read your question. Try:
UIBarButtonItem *finalBackButton = [[UIBarButtonItem alloc] initWithCustomView:backButton];
No need to have the backButtonView. You can pass in the UIButton as the custom view. I use this to create custom bar button items. This should fix your problem.
EDIT 2: The UIBarButtonItem class does not have an alpha property you can set. Also, modifying the alpha property of the UIButton that you set as the UIBarButtonItem's custom view won't affect the transparency of the UIBarButtonItem.
The only way you can do this is to modify the transparency of the source image being used for the UIButton.
Modify your original PNG to have the desired transparency you want (and based on your comments, you need a very low transparency). Use an image editing software / preview to fine tune the transparency before you export the PNG.

UIButton Custom Type with background color and transparent foreground image not working

I have the following custom button:
_button = [UIButton buttonWithType:UIButtonTypeCustom];
_button.backgroundColor = [UIColor darkGrayColor];
UIImage *bg = [UIImage imageNamed:#"btn_bg_highlighted.png"];
[_button setBackgroundImage:bg forState:UIControlStateHighlighted];
As expected, the button has a dark gray background. When I press the button, the background image is shown (red square).
Later in the program I'm setting the buttons foreground image, which is transparent (red rectangle). After that the gray background changes to white. When I press the button, it becomes gray.
When I'm setting the image right after [UIButton buttonWithType:UIButtonTypeCustom] it works great.
Do you know what the problem is?
OK, I'm stupid. I'm getting the image from a NSData object. At the server the UIImage is converted to NSData with UIImageJPEGRepresentation(image, quality). But this should be UIImagePNGRepresentation(image), otherwise the transparency gets lost at the client. Now everything works great!

How to Use Image as Button Background?

I have the following image representing my button:
I want to use that image to create a button that uses that as the background, but that is much wider than the image I supplied.
Here are the two methods that I have tried:
UIButton *emailSupportButton = [[UIButton alloc] initWithFrame:CGRectMake(25, 315, 200, 60)];
[emailSupportButton setTitle:#"Email Support" forState:UIControlStateNormal];
[emailSupportButton setImage:[UIImage imageNamed:#"toolbar-button"] forState:UIControlStateNormal];
This method results in the button image not being stretched and displaying exactly how the .png would display normally.
The other method I have tried is setting the background image, like so...
UIButton *emailSupportButton = [[UIButton alloc] initWithFrame:CGRectMake(25, 315, 200, 60)];
[emailSupportButton setTitle:#"Email Support" forState:UIControlStateNormal];
[emailSupportButton setBackgroundImage:[UIImage imageNamed:#"toolbar-button"] forState:UIControlStateNormal];
This method stretches the image in a really ugly fashion instead of achieving the desired effect, causing the button to be almost elliptical with a really ugly border.
Is the problem that I am not using the right method of creating a custom button, or that my image is not suitable for the task I am trying to accomplish? Is my image supposed to be rectangular and not include the button's border, letting UIButton take care of the border/rounding for me? Is my image supposed to already be the size of the button (this seems a bit limiting)?
The second method you listed (code-wise) is what you want. What you are missing is the stretchable image. Try this:
UIButton *emailSupportButton = [[UIButton alloc] initWithFrame:CGRectMake(25, 315, 200, 60)];
[emailSupportButton setTitle:#"Email Support" forState:UIControlStateNormal];
UIImage *backgroundImage = [UIImage imageNamed:#"toolbar-button"];
CGSize size = backgroundImage.size;
backgroundImage = [backgroundImage stretchableImageWithLeftCapWidth:size.width/2.0 topCapWidth:size.height/2.0];
[emailSupportButton setBackgroundImage:backgroundImage forState:UIControlStateNormal];
If you are deploying on iOS 5 and greater only, then you will want to use the new -[UIImage resizableImageWithCapInsets:(UIEdgeInsets)capInsets]; iOS 6 also adds -[UIImage resizableImageWithCapInsets:(UIEdgeInsets)capInsets resizingMode:(UIImageResizingMode)resizingMode];

Resources