UIButton setImage not working? - iphone

I have following code and when I call this method, it doesn't change the image of the button although there are images in the resources.
-(void)changeButton:(NSString*)button withURL:(NSString*)url {
timetableURL = url;
UIImage *btnImage;
if ([button isEqual:#"Browser"]) {
btnImage = [UIImage imageNamed:#"browser-button.png"];
[safariBtn addTarget:self action:#selector(onSafariButtonPress:) forControlEvents:UIControlEventTouchUpInside];
}
else if ([button isEqual:#"Timetable"]) {
btnImage = [UIImage imageNamed:#"browser-timetable.png"];
[safariBtn addTarget:self action:#selector(onTimetableButtonPress:) forControlEvents:UIControlEventTouchUpInside];
}
[safariBtn setImage:btnImage forState:UIControlStateNormal];
[btnImage release];
}
UPDATED
FYI: It's a button upside UIToolbar.

Some things that seem to be wrong with your code:
[btnImage release]
You've created that image using autorelease, you are not responsible for its release. This will most likely end up in weird stuff happening, i.e. what you encountered.
Are you sure that btnImage has contents after that if statement? is there a possibility that button is not equal to #"Browser" nor #"Timetable"?
Also, make sure the button is in its normal state.
Cheers

Try This ,
[safariBtn setBackgroundImage:btnImage forState:UIControlStateNormal];
No need to release btnImage ...

i think this should help you...
[safariBtn setImage:[UIImage imageNamed:#"browser-button.png"] forState:UIControlStateNormal];

may be this will help you : set the titles of button where you created it and then control if it equals the title.
[safariBtn setTitle:#"Safari" forState:UIControlStateNormal];
then control
-(void)changeButton:(NSString*)button withURL:(NSString*)url {
timetableURL = url;
UIImage *btnImage;
if ([button titleForState:UIControlStateNormal] isEqualToString:#"Safari"]) {
btnImage = [UIImage imageNamed:#"browser-button.png"];
[safariBtn addTarget:self action:#selector(onSafariButtonPress:) forControlEvents:UIControlEventTouchUpInside];
}
else if ([button titleForState:UIControlStateNormal] isEqualToString:#"Timetable"]) {
btnImage = [UIImage imageNamed:#"browser-timetable.png"];
[safariBtn addTarget:self action:#selector(onTimetableButtonPress:) forControlEvents:UIControlEventTouchUpInside];
}
[safariBtn setImage:btnImage forState:UIControlStateNormal];
[btnImage release];
}

Change
[button isEqual:#"Browser"]
To
[button isEqualToString:#"Browser"]
isEqual is testing for object equality, not string equality.
EDIT: OK, you say your button is inside a toolbar. In this case I assume you have added it as a customview to a UIBarbuttonItem? You need to go through the bar button item and set the image property on the custom view of the bar button item, I think (though I'm not sure) once you've added a button as a custom view, the bar button item makes it's own copy so you are not talking to it any more via safariBtn.
You can access the toolbar items via
for (UIBarButtonItem *barItem in self.toolbar.items)
Assuming this code is in your viewController. Your safariBtn will then be accessible via barItem.customView

Related

UIButton as switch

I'm trying to create a push-on-push-off-like button with custom images in Xcode4 for iOS.
The code I'm using is
- (IBAction)btnAll:(id)sender
{
UIButton *button = (UIButton *)sender;
button.selected = !button.selected;
}
That works fine for now.
But my problem is, that when I'm toggling on, I press it on, then it is popping off again and then finally on.
The app works, but that is really ugly, though.
I firstly set the "highlighted" image to on. So when I highlight the button, it is on and that popping to on. That works fine. But when I turn it off again, the problem is the same, in the reverse direction.
I tried to put that code:
- (IBAction)btnAll:(id)sender
{
UIButton *button = (UIButton *)sender;
if(button.selected)
{
[button setImage[UIImage imageNamed#"off.png"] forState:UIControlStateHighlighted];
}
else
{
[button setImage[UIImage imageNamed#"on.png"] forState:UIControlStateHighlighted];
}
button.selected = !button.selected;
}
But as long button.selected = !button.selected there is no difference.
So it won't make any change.
I also tried to trigger the IBAction on »Touch Down« but you can imagine how frustrating this will look like.
Has anybody got a solution for that problem?
Did anybody struggle with that one too?
Greets, thanks a lot
Julian
Don't manually switch the images around, just set the selected state's image in Interface Builder and swap the selected property over when the button is tapped.
I've had a similar problem to this before, the button works a little strangely when tapping. Try this code and let me know if it works
UIButton *button = (UIButton *)sender;
if(button.selected)
{
[button setImage:[UIImage imageNamed:#"off.png"] forState:UIControlStateHighlighted];
[button setImage:[UIImage imageNamed:#"off.png"] forState:UIControlStateSelected];
[button setImage:[UIImage imageNamed:#"off.png"] forState:UIControlStateHighlighted | UIControlStateSelected];
}
else
{
[button setImage:[UIImage imageNamed:#"on.png"] forState:UIControlStateHighlighted];
[button setImage:[UIImage imageNamed:#"on.png"] forState:UIControlStateSelected];
[button setImage:[UIImage imageNamed:#"on.png"] forState:UIControlStateHighlighted | UIControlStateSelected];
}
button.selected = !button.selected;
If (button.selected) {
[button setImage:[UIImage imageNamed:#"on.png"] forState:UIControlStateNormal];
} else {
[button setImage:[UIImage imageNamed:#"off.png"] forState:UIControlStateNormal];
}
When you tap and hold on a button the state is actually Highlighted & Selected so you need an image for both Highlight and selected state.
Agree with Jim, your code needs little modification as below...
[button setImage[UIImage imageNamed#"off.png"] forState:UIControlStateNormal];
[button setImage[UIImage imageNamed#"on.png"] forState:UIControlStateSelected];
Have two buttons created.
place buttons one above one.
Can set Default & Selected images using Custom Button option in design builder.
-(void)firstButtonClicked {
firstButton.hidden = YES;
secondButton.hidden = NO;
}
-(void)secondButtonClicked {
firstButton.hidden = NO;
secondButton.hidden = YES;
}
#Jim - when do u switch the isSelected state? isHighlighted gets called twice for every press. My hacked version of UIButton switch below : -
class ButtonSwitch: UIButton {
override func sendAction(_ action: Selector, to target: Any?, for event: UIEvent?) {
if allControlEvents == .touchUpInside {
isSelected.toggle()
}
super.sendAction(action, to: target, for: event)
}
}

UIScrollView clickable images iPhone

I have created a UIScrollView in my app - adapted from this sample code: http://developer.apple.com/iphone/library/samplecode/Scrolling/Introduction/Intro.html
But I have no idea how to make the images clickable
Any suggestions please?
Thanks!
Yeah... "Put them on UIButtons"
//get the image to use, however you want
UIImage* image = [product.images objectAtIndex:i];
UIButton* button = [[UIButton alloc] init];
//set the button states you want the image to show up for
[button setImage:image forState:UIControlStateNormal];
[button setImage:image forState:UIControlStateHighlighted];
//create the touch event target, i am calling the 'productImagePressed' method
[button addTarget:self action:#selector(productImagePressed:)
forControlEvents:UIControlEventTouchUpInside];
//i set the tag to the image #, i was looking though an array of them
button.tag = i;
//add the new button w/ the image to your scrollview
[ImagesScroller addSubview:button];
[button release];
Put them on UIButtons.

How do I make a UIBarButtonItem 'glow'?

In the Maps app, when you press the tracking button in the lower left hand corner, it glows showing that it's pressed. This makes it behave like a radio button, and it will un-glow once you move the map. Is there a simple way to but a button into the pressed state?
I believe you are looking for the showsTouchWhenHighlighted property for the UIButton class. Give this a try.
myButton.showsTouchWhenHighlighted = YES;
Set its style to UIBarButtonItemStyleDone.
You could make its customview a custom button like this:
`
UIImage *image = [UIImage imageNamed:#"someimage"];
UIImage *imageHL = [UIImage imageNamed:#"someimage_selected"];
button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage:image forState:UIControlStateNormal];
[button setImage:imageHL forState:UIControlStateHighlighted];
[button addTarget:self action:#selector(doStuff:) forControlEvents:UIControlEventTouchUpInside];
myBarButtonItem.customView = button;
`
Use UIBarButtonItemStylePlain.
UIBarButtonItemStylePlain
Glows when tapped.
If you have a UIBarButtonItem with image/text or UIBarButtonSystemItem, then use UIBarButtonItemStylePlain
barButton.style = UIBarButtonItemStylePlain;
If you have a UIBarButtonItem with a custom view, then, for each UIButton should add the following code:
uiButton.showsTouchWhenHighlighted = YES;

What is the best way to make a UIButton checkbox?

I am trying to make a standard check box for my iPhone app from a UIButton with a title and image. The button image changes between an "unchecked" image and a "checked" image.
At first I tried subclassing UIButton but UIButton has no -init*** method to use in my -init method.
What is the best way to do this?
Thanks in advance.
You shouldn't need to subclass the UIButton class. By design, Objective-C favors composition over inheritance.
UIButton is a subclass of UIControl, which has a selected property. You can use this property to toggle the on/off behaviour of a checkbox, just the same way a UISwitch does.
You can attach an action to the button's touched up inside event, and perform the toggling in there, something like this:
// when you setup your button, set an image for the selected and normal states
[myCheckBoxButton setImage:checkedImage forState:UIControlStateSelected];
[myCheckBoxButton setImage:nonCheckedImage forState:UIControlStateNormal];
- (void)myCheckboxToggle:(id)sender
{
myCheckboxButton.selected = !myCheckboxButton.selected; // toggle the selected property, just a simple BOOL
}
Set the images in the button:
[button setImage:uncheckedImage forState:UIControlStateNormal]
[button setImage:checkedImage forState:UIControlStateSelected]
Now all you need to do is:
button.selected = state
and the correct images will display.
All you need to do is set 2 different images for the states UIControlStateNormal and UIControlStateSelected, then in your selector, changed the selected property of the button.
Here is a working example (replace image names with your own):
- (void)loadView {
// ...
UIButton *chkBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[chkBtn setFrame:CGRectMake(0, 0, 300, 25)];
[chkBtn setImage:[UIImage imageNamed:#"UNCHECKED.png"]
forState:UIControlStateNormal];
[chkBtn setImage:[UIImage imageNamed:#"CHECKED.png"]
forState:UIControlStateSelected];
[chkBtn addTarget:self
action:#selector(chkBtnHandler:)
forControlEvents:UIControlEventTouchUpInside];
// Optional title change for checked/unchecked
[chkBtn setTitle:#"I am NOT checked!"
forState:UIControlStateNormal];
[chkBtn setTitle:#"I am checked!"
forState:UIControlStateSelected];
[self.view addSubview:chkBtn];
[chkBtn release], chkBtn = nil;
// ...
}
- (void)chkBtnHandler:(UIButton *)sender {
// If checked, uncheck and visa versa
[sender setSelected:!sender isSelected];
}
For anyone interested in the future - instead of doing it yourself just download the link below from GitHub and it has it subclassed from UIControl already and functions perfectly as a checkbox. Also includes a sample project on how easy it is to use:
https://github.com/Brayden/UICheckbox
I have used M13Checkbox in one of my projects. Works ok.
https://github.com/Marxon13/M13Checkbox
Did you try overriding the initWithCoder method, just in case it is loaded from a nib somehow?
UIImage* nonCheckedImage=[UIImage imageNamed:#"ic_check_box_outline_blank_grey600_48dp.png"];//[UIImage init
UIImage* CheckedImage=[UIImage imageNamed:#"ic_check_box_black_48dp.png"];//[UIImage init
//ic_check_box_black_48dp.png
[_checkBox setImage:CheckedImage forState:UIControlStateSelected];
[_checkBox setImage:nonCheckedImage forState:UIControlStateNormal];
}
- (IBAction)checkBoxToggle:(id)sender {
_checkBox.selected = !_checkBox.selected; // toggle the selected property, just a simple BOOL
}
the image you can use google icon
Try this:-
-(IBAction)clickCheckButton:(UIButton *)sender {
if (sender.tag==0) {
sender.tag = 1;
[sender setImage:[UIImage imageNamed:#"check.png"] forState:UIControlStateNormal];
}else
{
sender.tag = 0;
[sender setImage:[UIImage imageNamed:#"uncheck.png"] forState:UIControlStateNormal]; } } sender.tag = 0;
[sender setImage:[UIImage imageNamed:#"uncheck.png"] forState:UIControlStateNormal];
}
}
Why not use a switch - UISwitch? This is used to display an element showing the boolean state of a value.

Changing image on UIButton when user presses that button on an iPhone

I want to change the image on UIButton, when User presses that button. So, I wrote
btnthumbnail2 setImage:[UIImage imageNamed:#"leaderboard_ov.png"] forState:UIControlStateNormal];
and after that I changed the view.
The image is changing but not display the changed image.I think the controll goes to next view tha's why it is happening. But I want to show the change, How can I do this?? Plz help me for this..
I am using Interface Builder, in which I added a UIButton to the view.
I defined the button selected by default and selected my image for the selected state (Use drop-down list in Inspector window to choose "Selected State Configuration" before selecting the image).
Create an IBAction in the controller and connect the button to that action.
Then see the code below:
-(IBAction) toggleUIButtonImage:(id)sender{
if ([sender isSelected]) {
[sender setImage:unselectedImage forState:UIControlStateNormal];
[sender setSelected:NO];
} else {
[sender setImage:selectedImage forState:UIControlStateSelected];
[sender setSelected:YES];
}
}
This is the simplest way that I am doing it and it works every time
-(void)buttonTouched:(id)sender
{
UIButton *btn = (UIButton *)sender;
if( [[btn imageForState:UIControlStateNormal] isEqual:[UIImage imageNamed:#"icon-Locked.png"]])
{
[btn setImage:[UIImage imageNamed:#"icon-Unlocked.png"] forState:UIControlStateNormal];
// other statements
}
else
{
[btn setImage:[UIImage imageNamed:#"icon-Locked.png"] forState:UIControlStateNormal];
// other statements
}
}
You can use other similar checks for other states such as SELECTED, ENABLED, HIGHLIGHTED.
The code you have there should work fine, but I'm guessing that the button image doesn't appear changed until the next run through the event loop, so you don't see it before the view gets switched out.
It's kind of a hack, but you could try delaying the view change just slightly so that the button will update.
So instead of this:
[btnthumbnail2 setImage:[UIImage imageNamed:#"leaderboard_ov.png"] forState:UIControlStateNormal];
[self showMyOtherView];
Try this:
[btnthumbnail2 setImage:[UIImage imageNamed:#"leaderboard_ov.png"] forState:UIControlStateNormal];
[self performSelector:#selector(showMyOtherView) withObject:self afterDelay:0.01];
To change the image for the selected state you have to call setImage for state UIControlStateSelected. You can set separate images for different states (Normal, Highlighted, Disabled, Selected, etc).
If you want to change the image when the button is clicked, this way, works perfectly:
-(IBAction)buttonClicked: (id)sender
{
UIButton *buttonObj = (UIButton*)sender;
[buttonObj setBackgroundImage:[UIImage imageNamed:#"myImage.png"]
forState:UIControlStateNormal];
}
The simplest way to accomplish this is to simply set the highlighted image in Interface Builder.
Building on Nicsoft's answer.
-(void)viewDidLoad {
[super viewDidLoad];
[self.button setImage:[UIImage imageNamed:#"unselectedImageName"] forState:UIControlStateNormal];
[self.button setImage:[UIImage imageNamed:#"selectedImageName"] forState:UIControlStateSelected];
}
-(IBAction)toggleButton:(UIButton *)sender {
sender.selected = !sender.selected;
// Add logic here
}
I wrote code that does exactly this last night, and I didn't have to resort to any strange delaying tactics. In this particular case, I'm doing it from inside a tableViewCell. This is more code than you asked for, but it shows the whole process I used. As you can see, I chose not to have any special image for the period of time DURING a button touch.
// Button set up, inside cellForRowAtIndexPath:
// imageFrame is just the rect that you want the button to occupy
[self setFavorite:[[UIButton alloc] initWithFrame:imageFrame]];
[[self favorite] addTarget:self action:#selector(toggleFavorite:)
forControlEvents:UIControlEventTouchUpInside];
[cell addSubview:[self favorite]];
[self draw];
// definition of the callback specified above
- (void) toggleFavorite:(id) sender {
if (favoriteState == 0 ){
favoriteState = 1;
} else {
favoriteState = 0;
}
[self draw];
}
// the draw method, to set the images
// favOn and favOff are statically defined at the top of the class
- (void) draw {
if (favoriteState != 0) {
[[self favorite] setBackgroundImage:favOn forState:UIControlStateNormal];
[[self favorite] setBackgroundImage:favOn forState:UIControlStateHighlighted];
} else {
[[self favorite] setBackgroundImage:favOff forState:UIControlStateNormal];
[[self favorite] setBackgroundImage:favOff forState:UIControlStateHighlighted];
}
}
Hate to add to the plethora of answers, but:
Select images in IB for the button's default and selected states.
Connect an IBAction and keep it simple.
#IBAction func buttonTapped(sender: UIButton){sender.selected = !sender.selected}
Done.