2

UIImagePickerController 很容易使用,但是当我以前没有发现它时,我突然发现它令人恼火。发生的事情是,有时imagePickerController:didFinishPickingImage:editingInfo 委托方法似乎不起作用——即使在分配完成后,图像也不会显示在 UIImageView 中。有时会,有时不会,而且,我尝试过的每一段示例代码(来自网络,来自“Beginning iPhone 3 Development”一书等)都会出现同样的问题。我不知道为什么,这个问题发生在我的 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

4 回答 4

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];
}
于 2010-11-21T04:12:13.030 回答
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(并且在选择器前面时,您的应用程序的主视图控制器不可见!)丢弃其视图。

于 2009-11-04T05:46:50.197 回答
0

我曾经也有过一样的问题。打开 imagePicker 时会出现内存警告,并且 ViewController 会被丢弃。因此,您会丢失 ViewController 中的任何内容。例如,如果您有任何 UITextField,您也将丢失其内容。因此,当调用方法 didReceiveMemoryWarning 时,您需要将 ViewController 的状态存储在其他地方。您可以将值存储在 NSUserDefaults、文件、AppDelegate、...

将图像保存在文件中是一项耗时的任务。所以我的解决方案是将图像保存在内存中的 AppDelegate 中。我在委托中创建了一个 UIImage *image 变量。然后当 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;
    }
}
于 2010-06-18T14:22:25.020 回答
0

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 ??

于 2011-03-23T21:07:04.140 回答