UIButton Image does not change / update
Firstly, I am still new to objective-c and still trying to learn as best I can, so please bear with me.
I now have a UIButton that I created programmatically. When the button is pressed, the UIActionSheet is brought up with a choice of "Camera", "Select Photo" or "Cancel". After that, the button image should change to the selected image (if the camera is selected) or the image is selected (if the camera roll is selected).
My problem is that the button image doesn't change after dismissing the UIImagePicker. At first, the button was created as a subView of the tableView, and when I scrolled the tableView, it would update the button and the image changed (this is not how I wanted it to behave, of course). However, if the user decides that they want to change or delete the image, they simply press the button again and the third option "Delete Photo" is displayed on the UIActionSheet. After scrolling through the tableView, I realized that the button image does not change at all, but a new button was created on top of the old button instead, so I instead move the UIButton code to viewDidLoad (based on some information found here on stackoverflow). I also removed the ability to scroll the tableView as I don't need scrolling for it.
I have been trying to resolve this issue for a few days, how to update a button or view properly after rejecting a UIImagePicker or rejecting a UIActionSheet. I tried using setNeedsLayout and setNeedsDisplay but they didn't work to fix my problem (I might be putting them in the wrong place). Hopefully someone has some insight on this and I can be guided in an appropriate way to make this work. Also my code is presented:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
// Creates camera button and connects to camera menu UIActionSheet
UIButton *cameraButton = [UIButton buttonWithType:UIButtonTypeCustom];
[cameraButton addTarget:self action:@selector(showActionSheet:) forControlEvents:UIControlEventTouchUpInside];
cameraButton.titleLabel.lineBreakMode = UILineBreakModeWordWrap;
cameraButton.titleLabel.textAlignment = UITextAlignmentCenter;
cameraButton.frame = CGRectMake(9, 230, 80, 80);
[self.view addSubview:cameraButton];
picturePresent = NO;
NSLog(@"picturePresent = %@", picturePresent);
}
-(void)showActionSheet:(id)sender {
if (picturePresent == NO) {
UIActionSheet *cameraMenuSheet = [[UIActionSheet alloc] initWithTitle:@"Add Photo"
delegate:self
cancelButtonTitle:@"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:@"Camera", @"Choose Photo", nil];
[cameraMenuSheet showFromTabBar:self.tabBarController.tabBar];
}
else if (picturePresent == YES) {
UIActionSheet *cameraMenuSheet = [[UIActionSheet alloc] initWithTitle:@"Add Photo"
delegate:self
cancelButtonTitle:@"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:@"Remove Photo", @"Camera", @"Choose Photo", nil];
[cameraMenuSheet showFromTabBar:self.tabBarController.tabBar];
}
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
NSString *title = [actionSheet buttonTitleAtIndex:buttonIndex];
// Initialize UIImagePickerController
if ([title isEqualToString:@"Camera"]) {
// Camera
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePicker.delegate = self;
imagePicker.allowsEditing = NO;
imagePicker.showsCameraControls = YES;
imagePicker.mediaTypes = [NSArray arrayWithObjects:(NSString *)kUTTypeImage, nil];
[self presentModalViewController:imagePicker animated:YES];
newMedia = YES;
}
else if ([title isEqualToString:@"Choose Photo"]) {
// Photo library
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
imagePicker.delegate = self;
imagePicker.allowsEditing = NO;
imagePicker.mediaTypes = [NSArray arrayWithObjects:(NSString *)kUTTypeImage, nil];
[self presentModalViewController:imagePicker animated:YES];
newMedia = NO;
}
else if ([title isEqualToString:@"Remove Photo"]) {
picturePresent = NO;
}
}
- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex {
[self.view setNeedsDisplay];
}
// Method for saving image to photo album
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
// Access the uncropped image from info dictionary
UIImage *image = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
UIImage *scaledImage = [image scaleToSize:CGSizeMake(80.0, 80.0)];
if (newMedia == YES) {
// Save image
UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
}
resizedImage = scaledImage;
}
picturePresent = YES;
[self dismissModalViewControllerAnimated:NO];
}
-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[self dismissModalViewControllerAnimated:YES];
}
Also, now that I've moved my UIButton encoding to viewDidLoad I'm not sure where to put this piece of encoding:
{
if (picturePresent == NO) {
[cameraButton setTitle:@"Add\nPhoto" forState:UIControlStateNormal];
}
else if (picturePresent == YES) {
[cameraButton setImage:resizedImage forState:UIControlStateNormal];
}
}
Also setImage and setBackgroundImage have been used and still don't work the way I want them to. Let me know if you need more information, thanks!
EDIT:
Here are some screenshots to show what I am aiming for -
An "image" is an image that has been taken or selected and then scaled to fit the size of the button.
source to share
Haven't tested, but if you inject your cameraButton
member of yours UiViewController
so that you can access when needed you can call setImage: forState:
right after setting resizedImage
- no picturePresent
bool needed. And I think that it is setNeedsDisplay
not necessary either.
EDIT:
In your view, the controller header file does something like
...
@interface MyViewController : UIViewController
{
...
UIButton * cameraButton;
...
}
...
Somewhere in your implementation file (viewDidiLoad - Ok):
...
cameraButton = [UIButton buttonWithType:UIButtonTypeCustom];
...
[self.view addSubview:cameraButton];
...
And then implement whatever else you did and change the code didFinishPickingMediaWithInfo
as follows:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
...
[cameraButton scaledImage forState:UIControlStateNormal];
}
As I said, he hasn't tested it, but I think it should work.
source to share
I've been looking for answers for a long time. Here are some of them:
to change the button image the following code helped me:
[button.imageView setHighlighted:YES];
[button.imageView setHighlightedImage:[UIImage imageNamed:@"mypic.png"]];
[button.imageView setImage:[UIImage imageNamed:@"mypic.png"]];
.. eg. in viewDidLoad.
hope this helps ...
source to share