开发者

UIImagePickerController weirdness

UIImagePickerController is easy to use, but i'm all of a sudden finding it exasperating when I didn't find it so before. What's happening is that sometimes the imagePickerController:didFinishPickingImage:editingInfo delegate method does not seem to work -- the image will not show in the UIImageView even after the assignment was made. Sometimes it will, sometimes 开发者_C百科not, and furthermore, every single bit of example code i've tried (from the web, from the "Beginning iPhone 3 Development" book, etc.) exhibits the same problem. I'm at a loss as to why, and the problem happens on both my iPhone 3G as well as my 3GS, so I doubt that it's a hardware issue. These devices are running OS 3.1.2. The view controller is loaded from a xib file that contains one button and the UIImageView. I'd really like someone to tell me what stupid thing i'm obviously doing wrong :-)

Here is the code -- i've tried to make the smallest app I could that exhibits the problem:

#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>

@interface imagepickerViewController : UIViewController <UINavigationControllerDelegate, UIImagePickerControllerDelegate>
{
    IBOutlet UIButton *button;
    IBOutlet UIImageView *imageView;    
}

@property (nonatomic, retain) UIImageView *imageView;

- (IBAction)takepic;
- (void)usePic:(UIImage *)pic;

@end




#import "imagepickerViewController.h"

@implementation imagepickerViewController

@synthesize imageView;

- (IBAction)takepic 
{
    if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
    {
        UIImagePickerController *picker = [[UIImagePickerController alloc] init];
        picker.sourceType = UIImagePickerControllerSourceTypeCamera;        
        picker.delegate = self;

        [self presentModalViewController:picker animated:YES];
        [picker release];
    }
}

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)info
{
    [self usePic:image];
    [picker dismissModalViewControllerAnimated:YES];

    // after this method returns, the UIImageView should show the image -- yet very often it does not ...
}

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
    [picker dismissModalViewControllerAnimated:YES];
}

- (void)usePic:(UIImage *)picture
{
    imageView.image = picture;
}

@end


I came accross this issue recently too. My solution was to dismiss the modal UIImagePickerController view prior to using the image.

By dismissing the image picker, the previous view controller's view is reloaded, and the UIImageView which was to be the recipient of the chosen image is reloaded and no longer nil.

i.e. I changed from this:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
    // Wrong! imageView has been released by the UIViewController after a low memory warning and is now nil.
    [imageView setImage:image];
    [self dismissModalViewControllerAnimated:YES];
}

to this:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
    // Dismis the image picker first which causes the UIViewController to reload it's view (and therefore also imageView)
    [self dismissModalViewControllerAnimated:YES];
    [imageView setImage:image];
}


My guess: make sure you're handling didReceiveMemoryWarning correctly. Put a breakpoint or a debug printout or something to see if it's being hit, and then check what's happening next.

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
    NSLog(@"Got a memory warning");
}

The default handling is for UIViewControllers that are not visible (and your app's main view controller is not visible while the picker is in front of it!) to discard their views.


I have had the same problem. When the imagePicker is opened there is a memory warning and the ViewController is discarted. So you lose anything in your ViewController. For example if you have any UITextField you will also lose its content. So you need to store the state of your ViewController somewhere else when the method didReceiveMemoryWarning is called. You can store values in the NSUserDefaults, in files, in your AppDelegate,...

Saving an image in a file is a big time consumption task. So my solution has been to save the image in the AppDelegate, in memory. I've created an UIImage *image variable inside the delegate. Then when the imagePicker finishes I store the image in that field:

- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info {
       UIImage *editedImage = [info objectForKey:UIImagePickerControllerEditedImage];
       imageView.image = editedImage; // it works if no memory warning is received

       YourAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
       delegate.image = editedImage;
}

Then if the ViewController has been discarted it's needed to read the stored image from the AppDelegate in the viewDidLoad method.

- (void)viewDidLoad {
    [super viewDidLoad];

    // if you have used NSUserDefalts to store the state of your UITextFields
    // when the didReceiveMemoryWarning was called
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSString *name = [defaults objectForKey:@"name"];
    if (name != nil) {
        textFieldName.text = name;
    }

    // show the saved image
    YourAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
    UIImage *image = delegate.image;
    if (image != nil) {
        imageView.image = image;
    }
}


I've tried all these techniques and no joy. The image view does change shape to match the photo but the only thing that display's is the background. and if i attempt to take a photo the second time it works...

This doesn't make any sense whatsoever...could it be a problem with the XIB ??

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜