UIImagePickerController很奇怪

时间:2009-11-04 05:26:06

标签: iphone uiimagepickercontroller

UIImagePickerController很容易使用,但是当我以前没有找到它时,我突然觉得它很恼火。发生的事情是有时 imagePickerController:didFinishPickingImage:editingInfo委托方法似乎不起作用 - 即使在分配完成后,图像也不会显示在UIImageView中。有时它会,有时不会,而且,我尝试过的每一段示例代码(来自网络,来自“初学iPhone 3开发”等书)都表现出同样的问题。我不知道为什么,问题发生在我的iPhone 3G和3GS上,所以我怀疑这是硬件问题。这些设备正在运行OS 3.1.2。视图控制器是从包含一个按钮和UIImageView的xib文件加载的。我真的希望有人告诉我,我显然做错了什么愚蠢的事情: - )

这是代码 - 我试图制作出能够解决问题的最小应用程序:

#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

4 个答案:

答案 0 :(得分:4)

我最近也遇到了这个问题。我的解决方案是在使用图像之前关闭模态UIImagePickerController视图。

通过关闭图像选择器,重新加载前一个视图控制器的视图,并且重新加载作为所选图像的接收者的UIImageView,不再为零。

即。我改变了这个:

- (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];
}

到此:

- (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];
}

答案 1 :(得分:3)

我的猜测:确保您正确处理didReceiveMemoryWarning。放置断点或调试打印输出或其他东西,看它是否被击中,然后检查接下来发生了什么。

- (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");
}

默认处理是针对不可见的UIViewControllers(并且当应用程序位于其前面时,您的应用程序的主视图控制器不可见!)以丢弃其视图。

答案 2 :(得分:0)

我遇到了同样的问题。打开imagePicker时会出现内存警告,并且放弃了ViewController。所以你在ViewController中丢失了任何东西。例如,如果您有任何UITextField,您也将丢失其内容。因此,在调用方法didReceiveMemoryWarning时,您需要将ViewController的状态存储在其他位置。您可以将值存储在NSUserDefaults,文件中,AppDelegate中......

将图像保存在文件中是big time consumption task。所以我的解决方案是将图像保存在内存中的AppDelegate中。我在委托中创建了一个UIImage *图像变量。然后当imagePicker完成时,我将图像存储在该字段中:

- (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;
}

然后,如果ViewController已被放弃,则需要在viewDidLoad方法中从AppDelegate读取存储的图像。

- (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;
    }
}

答案 3 :(得分:0)

我尝试过所有这些技巧而没有快乐。图像视图确实会改变形状以匹配照片,但唯一显示的是背景。如果我第二次尝试拍照...

这没有任何意义......这可能是XIB的问题吗?