-1

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

1 Answers1

0

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.

Paulw11
  • 108,386
  • 14
  • 159
  • 186
  • That worked! One quick followup question, when it dismisses the popover it goes to the previous screen, what should I change so that it stays on the same view controller, and once it does that so the chosen image is shown in the UIImage spot. Thanks again for your help! – user3927993 Aug 11 '14 at 11:08
  • I've tried the following code, and it works but I can't declare it twice for both methods and I'm wondering how to implement this. - (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { UIImage * image = info[UIImagePickerControllerOriginalImage]; imageView.image = image; – user3927993 Aug 11 '14 at 11:21
  • It is going to the previous screen because you are calling `[self dismissViewControllerAnimated:YES completion:nil];` - Perhaps you meant to call `self.popoverController dismissPopoverAnimated:` - I was wondering about that. I am not sure I understand your previous comment. Are you asking how to have the one class act as a delegate for two `UIImagePickerControllers`? – Paulw11 Aug 11 '14 at 11:29
  • Thanks, and yes I want the uiimage to be updated from either a picture that was taken or from the library. – user3927993 Aug 11 '14 at 11:40
  • You can either workout which picker you are handling in the delegate - examine the tag property for example - or create a UIPopoverController subclass to drive your popover and make it the delegate of the ImagePicker. It will need to pass the selected information back to the main class - You can do this by implementing the `popoverControllerShouldDismissPopover` delegate method and examining a property of your subclass – Paulw11 Aug 11 '14 at 11:42
  • Thanks for both approaches! originally I had wanted to implement a popover that would give the user both options and have it choose from there, would that still be able to be implemented? – user3927993 Aug 11 '14 at 12:24
  • Perhaps you could put a tab bar at the bottom of your pop over, or you could add a "camera" icon as the first picture in the image picker and if they select that, then switch to the camera picker – Paulw11 Aug 11 '14 at 12:31
  • Thank you! now going back to the other question regarding tags. I've added a self.imagePicker.tag =20; and I get a property tag not found on object of type error – user3927993 Aug 11 '14 at 12:36
  • Sorry, that is my bad. UIImagePickerControllers don't have a tag property as they aren't a UIView subclass. You could check the `sourceType` property to work out which picker it was – Paulw11 Aug 11 '14 at 12:38
  • Thank you for all your help! and here's what I tried. i get an "expected ']'" error on of the if line, im not sure why. I've edited my code snippet above for easier viewing – user3927993 Aug 11 '14 at 13:02
  • - (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 – user3927993 Aug 11 '14 at 13:03