Search code examples
iosipaduiimagepickercontrolleruipopovercontrollerpopover

UIpopoverController dealloc reached while popover is still visible in Ipad


I am showing the camera roll using popover and user is able to select a picture and have that be shown in the UIImageView.

The code below will present the picker but upon clicking on a picture I get an NSexception. I've looked at similar questions on here, and google and found no solution. My popover is set to strong. Any help would be appreciated

#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
#import <Foundation/Foundation.h>
#import "Pilot.h"

@interface PilotViewController : UIViewController <UIImagePickerControllerDelegate, UINavigationControllerDelegate,UIPopoverControllerDelegate>




@property (readonly, nonatomic) UIImage                     *viewImage;

@property (weak, nonatomic    ) IBOutlet UIImageView        *imageView;

@property (nonatomic, strong  ) UIPopoverController         *popoverController;
@property (strong, retain     ) UIImagePickerController     *imagePicker;

//PilotViewController.m

#import "PilotViewController.h"

@interface PilotViewController ()


@end

@implementation PilotViewController
@synthesize popoverController;
@synthesize imagePicker;
@synthesize imageView;






//Button to open library
- (IBAction)library:(id)sender{

    //Create image picker controller

    self.imagePicker  = [[UIImagePickerController alloc]init];

    //Set source to the photo library
    self.imagePicker.delegate       = self;
   self. imagePicker.sourceType     = UIImagePickerControllerSourceTypePhotoLibrary;
    self.imagePicker.allowsEditing  = NO;

    self.popoverController          = [[UIPopoverController alloc]
                                       initWithContentViewController:imagePicker];
    self.popoverController.delegate = self;
    CGRect popoverRect = [self.view convertRect:[self.view frame]
                                       fromView:[self.view superview]];

    popoverRect.size.width = MIN(popoverRect.size.width, 80) ;
    popoverRect.origin.x  = popoverRect.origin.x+150;

    [self.popoverController
     presentPopoverFromRect:popoverRect
     inView:self.view
     permittedArrowDirections:UIPopoverArrowDirectionLeft
     animated:YES];
}



-(void) imagePickerController:(UIImagePickerController *)picker didfinishPickingImage:(UIImage *)image
                  editingInfo: (NSDictionary *) editinginfo
{
    imageView.image                = image;
    [self dismissViewControllerAnimated:YES completion:nil];
}






- (IBAction)camera:(id)sender{


    if ([UIImagePickerController isSourceTypeAvailable:
         UIImagePickerControllerSourceTypeCamera])

    {

     //Create image picker controller

    self.imagePicker                = [[UIImagePickerController alloc]init];

    self.imagePicker.delegate       = self;
    self.imagePicker.sourceType=
    UIImagePickerControllerSourceTypeCamera;
    self.imagePicker.allowsEditing  = NO;

    self.imagePicker.cameraDevice =
    UIImagePickerControllerCameraDeviceRear;
    [self presentViewController:imagePicker animated:YES completion:nil];
}

    else
    {
    UIAlertView *alert      = [[UIAlertView alloc]
                              initWithTitle:@"Camera failed to open"
                              message:@"Camera is not available"
                              delegate:nil
                              cancelButtonTitle:@"OK"
                              otherButtonTitles: nil];
        [alert show];
    }




}

#pragma mark Image Picker Delegate Methods

//on cancel dimiss picker controller

-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
    [self dismissViewControllerAnimated:YES completion:nil];


}

//Used when user has chosen an image

- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    UIImage * image                 = info[UIImagePickerControllerOriginalImage];
    imageView.image                = image;
    [self dismissViewControllerAnimated:YES completion:nil];
}



    @end





- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {

    if ([picker sourceType == UIImagePickerControllerSourceTypeCamera]){
        UIImage * image                 = info[UIImagePickerControllerOriginalImage];
        imageView.image                 = image;
        [self dismissViewControllerAnimated:YES completion:nil];


    }else{


   UIImage * image                 = info[UIImagePickerControllerOriginalImage];
   imageView.image                 = image;
}

          }

    @end

Solution

  • Your problem is that you are dismissing the view without dismissing the popover first.

    You can make sure it is dismissed overriding viewWillDisappear

    -(void) viewWillDisappear:(BOOL)animated {
        [super viewWillDisappear:animated];
        if (self.popoverController != nil) {
            [self.popoverController dismissPopoverAnimated:animated];
            self.popoverController=nil;
        }
     }
    

    You should also add the UIPopoverControllerDelegate method popoverControllerDidDismissPopover: -

    - (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController {
        self.popoverController=nil;
    }
    

    UPDATE

    Your if statement in the didFinishPickingMediaWithInfo should be either

    if ([picker sourceType] == UIImagePickerControllerSourceTypeCamera){
    

    or

    if (picker.sourceType == UIImagePickerControllerSourceTypeCamera){
    

    You had the ] in the wrong place.