2 Stimmen

UIImagePickerController Seltsamkeiten

UIImagePickerController ist einfach zu bedienen, aber ich bin ganz plötzlich finden es ärgerlich, wenn ich nicht finden es so vor. Was passiert ist, dass manchmal die imagePickerController:didFinishPickingImage:editingInfo Delegate-Methode scheint nicht zu funktionieren - das Bild wird nicht in der UIImageView angezeigt, auch nachdem die Zuordnung vorgenommen wurde. Manchmal wird es, manchmal nicht, und darüber hinaus jedes einzelne Bit des Beispielcodes, die ich versucht habe (aus dem Web, aus dem "Beginning iPhone 3 Development" Buch, usw.) zeigt das gleiche Problem. Ich bin ratlos, warum, und das Problem tritt sowohl auf meinem iPhone 3G als auch auf meinem 3GS auf, so dass ich bezweifle, dass es ein Hardware-Problem ist. Auf diesen Geräten läuft OS 3.1.2. Der View Controller wird von einer xib-Datei geladen, die eine Schaltfläche und die UIImageView enthält. Ich würde mich wirklich freuen, wenn mir jemand sagen könnte, was ich offensichtlich falsch mache :-)

Hier ist der Code - ich habe versucht, die kleinste Anwendung zu machen, die ich konnte, die das Problem zeigt:

#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

4voto

theconnorpower Punkte 223

Auch ich bin kürzlich auf dieses Problem gestoßen. Meine Lösung war, das modale Fenster zu schließen UIImagePickerController vor der Verwendung des Bildes zu überprüfen.

Durch das Verlassen des Bildauswählers wird die Ansicht des vorherigen View-Controllers neu geladen, und die UIImageView die der Empfänger des gewählten Bildes sein sollte, wird neu geladen und ist nicht mehr Null.

d.h. ich habe mich von diesem geändert:

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

dazu:

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

3voto

David Maymudes Punkte 5659

Mein Tipp: Stellen Sie sicher, dass Sie die didReceiveMemoryWarning richtig. Setzen Sie einen Haltepunkt oder einen Debug-Ausdruck oder etwas anderes, um zu sehen, ob er getroffen wird, und prüfen Sie dann, was als nächstes passiert.

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

Standardmäßig werden UIViewController, die nicht sichtbar sind (und der Haupt-Viewcontroller Ihrer Anwendung ist nicht sichtbar, solange der Picker vor ihm steht), so behandelt, dass sie ihre Views verwerfen.

0voto

gimenete Punkte 2589

Ich hatte das gleiche Problem. Wenn der imagePicker geöffnet wird, gibt es eine Speicherwarnung und der ViewController wird abgebrochen. So verlieren Sie alles in Ihrem ViewController. Wenn Sie zum Beispiel ein UITextField haben, verlieren Sie auch dessen Inhalt. Sie müssen also den Zustand Ihres ViewControllers irgendwo anders speichern, wenn die Methode didReceiveMemoryWarning aufgerufen wird. Sie können Werte in den NSUserDefaults, in Dateien, in Ihrem AppDelegate,... speichern.

Das Speichern eines Bildes in einer Datei ist eine große zeitaufwendige Aufgabe . Meine Lösung bestand also darin, das Bild im AppDelegate im Speicher zu speichern. Ich habe eine UIImage *image Variable innerhalb des Delegaten erstellt. Dann, wenn der imagePicker beendet, speichere ich das Bild in diesem Feld:

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

Dann, wenn der ViewController nicht gestartet wurde, muss das gespeicherte Bild aus dem AppDelegate in der viewDidLoad Methode gelesen werden.

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

0voto

MB. Punkte 691

Ich habe all diese Techniken ausprobiert, aber ohne Erfolg. Die Bildansicht ändert die Form, um das Foto anzupassen, aber das einzige, was angezeigt wird, ist der Hintergrund. und wenn ich versuche, ein Foto das zweite Mal zu nehmen, funktioniert es...

Das macht überhaupt keinen Sinn... könnte es ein Problem mit dem XIB sein?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X