Question

I am new to IOS and Objective-C , and I try to set Image for a UIButton. Wen I click the button , the button will change image1. If I click the button one again , it will change to image2

First, I set the image in Viewdidload like the following code.

    @interface AITPreviewViewController ()
    {
        VLCMediaPlayer *mediaPlayer ;
        BOOL recording ;
        BOOL recordMode;
    }
    - (void)viewDidLoad
    {
        recordMode = YES;
        UIButton *modeChangeButton = [[UIButton alloc] initWithFrame:CGRectMake(200, 450, 60, 60)];
        [modeChangeButton setBackgroundImage:[UIImage imageNamed:@"recordmode.PNG"] forState:UIControlStateNormal];

        [self.view addSubview:modeChangeButton];
    }

When I click the button , the button will change the image. The code is like the following:

- (IBAction)modeButtonClick:(id)sender {
    NSLog(@"modeButtonClick..!!!!!!");

    if (recordMode == YES) {
        NSLog(@"modeButtonClick..%hhd = " , recordMode);
        [self.modeChangeButton setBackgroundImage:[UIImage imageNamed:@"photomode.png"] forState:UIControlStateNormal];
        recordMode = NO;

    }else if (recordMode == NO){
        NSLog(@"modeButtonClick..%hhd = " , recordMode);
        [self.modeChangeButton setBackgroundImage:[UIImage imageNamed:@"recordmode.png"] forState:UIControlStateNormal];
        recordMode = YES;
    }

}

When I click the image on the button , the image of the button become dark in color. It seems the button has been press. But the - (IBAction)modeButtonClick:(id)sender didn't called.

When I click the blank space (the side of image) , the button has been press. The - (IBAction)modeButtonClick:(id)sender has been called. And the image also change to other image.

I am sure I have set action in header file and .m file.

The above describe is like the following picture. enter image description here

It seems the button is cover by image , and the image and the button is not the same. Why this happened ?? How to solve this problem ?

Thanks in advance.

Was it helpful?

Solution

Couple of changes that you could implement:

First: Change the setBackgroundImage to setImage. For example: [self.modeChangeButton setImage: [UIImage imageNamed: @"recordmode.png" forControlState: UIControlStateNormal];

That way, if you have set an image to the button by mistake, this will overwrite it.

Second: Make sure you have connected your reference outlets (IBOutlet) and actions (IBActions) in Interface builder - whether XIB files, or storyboard. If you don't link the the interface objects there to those in your code, they won't work.

Third: If it still does not work, try adding this line to your viewDidLoad

[self.modeChangeButton addTarget:self @selector(modeButtonClick:) forControlEvents:UIControlEventTouchUpInside];

Fourth: Change this line in your viewDidLoad:

UIButton *modeChangeButton = [[UIButton alloc] initWithFrame:CGRectMake(200, 450, 60, 60)];

to:

self.modeChangeButton = [[UIButton alloc] initWithFrame:CGRectMake(200, 450, 60, 60)];

This should solve your problem.

OTHER TIPS

This code is adding a new button on top of your self.modeChangeButton which I'm assuming is coming from a xib or storyboard.

 - (void)viewDidLoad
    {
        recordMode = YES;
        UIButton *modeChangeButton = [[UIButton alloc] initWithFrame:CGRectMake(200, 450, 60, 60)];
        [modeChangeButton setBackgroundImage:[UIImage imageNamed:@"recordmode.PNG"] forState:UIControlStateNormal];

        [self.view addSubview:modeChangeButton];
    }

Do this instead...

 - (void)viewDidLoad {
        self.recordMode = YES;
    }

- (void)setRecordMode:(BOOL)recordMode {
    _recordMode = recordMode;
    UIImage *imageForMode = recordMode ? [UIImage imageNamed:@"photomode.png"] : [UIImage imageNamed:@"recordmode.png"];
    [self.modeChangeButton setBackgroundImage:imageForMode forState:UIControlStateNormal];
}

- (IBAction)modeButtonClick:(id)sender {
    self.recordMode = !self.recordMode;
}

Check your button size and make the frame size closer to the image size. And try to maintain the two images as like below.

- (void)viewDidLoad
{
      UIButton *modeChangeButton = [[UIButton alloc] initWithFrame:CGRectMake(200, 450, 60, 60)];

      [modeChangeButton setImage:[UIImage imageNamed:@"recordmode.PNG"] forState:UIControlStateNormal];

      [modeChangeButton setImage:[UIImage imageNamed:@"photomode.png"] forState:UIControlStateSelected];

      [modeChangeButton addTarget:self action:@selector(modeButtonClick:) forControlEvents:UIControlEventTouchUpInside];

      [self.view addSubview:modeChangeButton];
}

- (IBAction)modeButtonClick:(id)sender 
{
    sender.selected = !sender.selected;
}

Try modifying you viewDidLoad method as follows.

- (void)viewDidLoad
{
   [super viewDidLoad];

   UIButton *modeChangeButton = [[UIButton alloc] initWithFrame:CGRectMake(200, 300, 60, 60)];
   [modeChangeButton setBackgroundImage:[UIImage imageNamed:@"recordmode.PNG"] forState:UIControlStateNormal];

   // You might need to add following two lines into your code.
   [modeChangeButton addTarget:self action:@selector(modeButtonClick:) forControlEvents:UIControlEventTouchUpInside];
   self.modeChangeButton = modeChangeButton;

   [self.view addSubview:modeChangeButton];
}

Above solution should work. As I see, you have referencing property named modeChangeButton in your modeButtonClick: method. But you are not assigning the created button into your property. Also you have to set the action selector to your button.

As a improvement, you can do this to improve performance of your application. Without setting the background image on click event, you can select/deselect the button. With this you don't need to maintain boolean flags, which may introduce new bugs to your application.

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    UIButton *modeChangeButton = [[UIButton alloc] initWithFrame:CGRectMake(200, 300, 60, 60)];
    [modeChangeButton setBackgroundImage:[UIImage imageNamed:@"recordmode.png"] forState:UIControlStateNormal];
    [modeChangeButton setBackgroundImage:[UIImage imageNamed:@"photomode.png"] forState:UIControlStateSelected];

    [modeChangeButton addTarget:self action:@selector(modeButtonClick:) forControlEvents:UIControlEventTouchUpInside];
    self.modeChangeButton = modeChangeButton;

    [self.view addSubview:modeChangeButton];
}

- (IBAction)modeButtonClick:(id)sender {
    NSLog(@"modeButtonClick..!!!!!!");
    [self.modeChangeButton setSelected:![self.modeChangeButton isSelected]];
}

Hope this helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top