Can't get object while using UIImage imageNamed:#"cardback" - ios

I'm a beginner at Objective C.
I'm trying to add a button to the storyboard. When clicked, the button's background will be changed to another image. However, I'm try to get the background image using :
[sender setBackgroundImage: [UIImage imageNamed:#"cardback.jpg"] forState:UIControlStateApplication];
It seems that [UIImage imageNamed:#"cardback.jpg"] just doesn't get the image object for me.
codes

You are using wrong control state flag. You need to use UIControlStateNormal instead of UIControlStateApplication for getting the desired result. Refer UIControlState for more info. Also you don't need to specify the image extension (because you are loading the image from asset catalog), so remove .jpg from the code.
Change:
[sender setBackgroundImage: [UIImage imageNamed:#"cardback.jpg"] forState:UIControlStateApplication];
to
[sender setBackgroundImage: [UIImage imageNamed:#"cardback"] forState:UIControlStateNormal];

Related

Blue image for buttons

I have buttons in my costoum cell , and i'm setting the images from code . But something strange is happening. My images are blue .
BOOL isTheObjectThere = [self.favoriteArry containsObject:self.tableData[indexPath.row]];
if (isTheObjectThere==TRUE) {
cell.favBtn.hidden = NO;
[cell.favBtn setImage:[UIImage imageNamed:#"favorite_star.png"] forState:UIControlStateNormal];
cell.favBtn.tag = indexPath.row;
[cell.favBtn addTarget:self action:#selector(unfavoriteBtn:) forControlEvents:UIControlEventTouchUpInside];
As mentioned in the comments, you should create the button with a UIButtonTypeCustom type in case it's currently set to UIButtonTypeSystem and you want to avoid the tint color from taking over. Alternatively, you can set the image rendering mode to make sure you always get the original image and not a tinted one:
[[UIImage imageNamed:#"favorite_star.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]

How to compare self.button.currentImage to an image?

I am trying to create a button represented by an image which whenever is pressed changes the image to the other one so that I can know which image is currently selected.
- (IBAction)imageWasPressed:(id)sender {
UIImage *imageWork = [UIImage imageNamed:#"icn_work"];
NSData *data1 = UIImagePNGRepresentation(self.imageButton.currentImage);
NSData *data2 = UIImagePNGRepresentation(imageWork);
if (data1==data2){
[self.imageButton setImage:[UIImage imageNamed:#"icn_personal"] forState:UIControlStateNormal];}
}
I have also tried this but it didn't work:
- (IBAction)imageWasPressed:(id)sender {
if ([[self.imageButton imageForState:UIControlStateNormal] isEqual:[UIImage imageNamed:#"icn_work"]]){
[self.imageButton setImage:[UIImage imageNamed:#"icn_personal"] forState:UIControlStateNormal];}
}
The line which changes the images works but I can't compare the two images. Any help would be much appreciated! Thank you!
This is rather unconventional approach, and I would recommend keeping track of your selection some other way.
But to answer the issue at hand, it does not work because you are comparing pointers, not data.
data1 * will always be different to data2 *.
From the documentation:
isEqualToData:
Compares the receiving data object to otherData.
- (BOOL)isEqualToData:(NSData *)otherData
If you want to change button image regarding it's state you can assign different images for different states.
[self.imageButton setImage:image1 forState:UIControlStateNormal];
[self.imageButton setImage:image2 forState:UIControlStateHighlighted];
[self.imageButton setImage:image3 forState:UIControlStateSelected];
Since you can get button state and you know what image you set for the state you can get image as well.
if ([data1 isEqualToData: data2])
instead of
if (data1==data2)

Conflicting UIBarbuttonItem's tintcolor and image

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"

UIButton apperance change disclosure too why? how to avoid it?

So when I customize my button I put a background image like this:
- (void) styleUIButtons {
UIImage *buttonNormalBg = [[UIImage imageNamed:#"button_normal" ] stretchableImageWithLeftCapWidth:0 topCapHeight:0];
UIImage *buttonSelectedBgb = [[UIImage imageNamed:#"button_selected" ] stretchableImageWithLeftCapWidth:0 topCapHeight:0];
id appereance = [UIButton appearance];
[appereance setTintColor:self.mainNavigationBarTextColor];
[appereance setBackgroundImage:buttonNormalBg forState:UIControlStateNormal];
[appereance setBackgroundImage:buttonSelectedBgb forState:UIControlStateHighlighted];
}
But the disclosure indicator of the table change horribly to a single line. Why does this happened? and how can I avoid it? Am I customizing the button wrongly?
stretchableImageWithLeftCapWidth:topCapHeight: is deprecated.
Use resizableImageWithCapInsets: instead.
I copied your code and the images are working fine for me.
The only thing I had to add was a frame.
The tintColor only seems to work when there aren't background images.

UIButton set image for state normal, hide that image in different states

[button setImage: [UIImage imageNamed:#"Back.png"] forState:UIControlStateNormal];
[button setTitle: #"Title" forState:UIControlStateSelected];
I would like the button to display the image in normal state but the word "Title" in selected state. But I can't get this code to work. It displays Image when I click the button to selected state and the Image covers the title. I can't get rid of the image in selected state.
[button setImage: [UIImage imageNamed:#"Back.png"] forState:UIControlStateNormal];
[button setImage: [UIImage imageNamed:#"Back2.png"] forState:UIControlStateSelected];
But this works. The image flips from Back to Back2. Or the other way works too
[button setImage: [UIImage imageNamed:#"Back.png"] forState:UIControlStateSelected];
[button setTitle: #"Title" forState:UIControlStateNormal];
It is so simple and I started to think it is UIButton bug.
Has anyone tried this before?
Add some small transparent image (1px is enough) to your project and name it, for example, transparent.png. Then add this line to the code:
[button setImage: [UIImage imageNamed:#"transparent"] forState:UIControlStateSelected];
The other and much simpler solution is to use interface builder and set images for diferent states. In this case you even don't need to use the transparent image; simply left the Image field empty for Selected state.
Like #codeplasma answer, but no need to add a transparent image, just create an empty UIImage:
button.setImage(UIImage(), forState: .selected)
In Objective-C you would create it with [UIImage new].
You have to explicitly set the button state to selected in some UIButtons(like the rounded rect button), it does not happen automatically upon clicking on it.
Bug?
No, it's not a bug, UIButton is designed this way, and here's why: when you set an image for the UIButton's UIControlStateNormal (normal state), it will preserve it throughout the other states (selected, disabled, highlighted) in the event you did not specify an image for those other states.
This means you can set up your button with a single image, the system adds a dark highlight in highlight state and makes the button look like it's alpha 0.5 in disabled state.
You might think setting the image to nil for the selected state will get rid of it for that state, but of course when the state changes, it will see that it doesn't have an image for that state (it's nil !), but it does for state UIControlStateNormal, so it will use that one instead, thus you are stuck with the same image!
Note that if you set the image for a different state then normal, it would have only shown for that state.
Workaround
Honestly your intentions with the button's image/title sound a little odd... Maybe you're new to iOS, maybe with some more info about what your button is and is supposed to be doing, we can suggest a better solution.... but the easiest way to workaround this with the information you've given us is to give a valid image for the selected state, one which is preferably transparent, and it could be 1x1 pixels also to save on space.
Otherwise you can do this, create a UIImage at runtime to use as a placeholder acting as your image, but would be a good idea to cache this, perhaps create it once and hold it in an iVar.
// Create a 1x1 UIImage at runtime
UIGraphicsBeginImageContext((CGSize){1.0f,1.0f});
UIImage *runtimeImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// Setup your button
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btn.frame = CGRectMake(20.0, 20.0, 100.0, 100.0);
// set the image for each state
[btn setImage:[UIImage imageNamed:#"Back.png"] forState:UIControlStateNormal];
[btn setImage:runtimeImage forState:UIControlStateSelected];
// have your text for the normal state
[btn setTitle:#"selected !" forState:UIControlStateNormal];
Instead of using setImage, I suggest to use SetBackgroundImage for this scenario. Here is a solution that works for me for a similar solution:
UIImage *cardBackImage = [UIImage imageNamed:#"card.png"];
UIImage *cardFrontImage = [UIImage imageNamed:#"transparent.png"];
[cardButton setBackgroundImage:cardFrontImage forState:UIControlStateSelected];
[cardButton setBackgroundImage:cardFrontImage forState:UIControlStateSelected|UIControlStateDisabled];
[cardButton setBackgroundImage:cardBackImage forState:UIControlStateNormal];

Resources