Search code examples
uiimagepickercontrollerios6.1non-modal

iOS 6.1 - How do I implement imagePickerControllerDidCancel for a non-modal UIImagePickerController


On iOS 6.1, I am displaying a UIImagePickerController non-modally in one tab of a UITabBar.

In my init:

self.picker = [[UIImagePickerController alloc] init];
self.picker.sourceType = UIImagePickerControllerSourceTypeCamera;
self.picker.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];
self.picker.delegate = self;
self.picker.allowsEditing = NO;
[self.view addSubview:self.picker.view];

I have implemented:

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
    return;
}

Since I never called:

[picker presentViewController:(UIViewController *) animated:(BOOL) completion:^(void)completion];

I shouldn't need to call:

[picker dismissViewControllerAnimated:NO completion:nil];

But, when I press the Cancel button, the Cancel button is grayed out and the UIImagePickerController seems to lock up. Some of the controls work, like the image/video switch and the reverse camera button, but the button to take a picture is frozen.

If I go to a different tab and return to the Camera tab, the UIImagePickerController is reset and fine again. The only code executed in this case is viewWillAppear and viewDidAppear which shouldn't have anything relevant to this situation.

On iOS 7,nothing locks up when the Cancel button is pressed.

Since the UIImagePickerController is always displayed in the tab, I don't really have a need for a cancel button so how would I either:

  • Hide or disable the Cancel button
  • Implement imagePickerControllerDidCancel so things do not lock up

Solution

  • Implemented a Camera Overlay View and things work fine.

        self.picker = [[UIImagePickerController alloc] init];
        self.picker.sourceType = UIImagePickerControllerSourceTypeCamera;
        self.picker.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];
        self.picker.delegate = self;
        self.picker.allowsEditing = NO;
        self.picker.showsCameraControls = NO;
    
        UIView *clearView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
        clearView.opaque = NO;
        clearView.backgroundColor = [UIColor clearColor];
    
        UIToolbar *toolBar=[[UIToolbar alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height-self.tabBarController.tabBar.frame.size.height-55, self.view.frame.size.width, 55)];
        toolBar.barStyle =  UIBarStyleBlackOpaque;
        NSArray *items=[NSArray arrayWithObjects:
                        [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil],
                        [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCamera target:self action:@selector(takePicture)],
                        [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil],
                        nil];
        [toolBar setItems:items];
    
        UIView *overlayView = [[UIView alloc] initWithFrame:self.view.bounds];
        [overlayView addSubview:clearView];
        [overlayView addSubview:toolBar];
    
        [self.picker setCameraOverlayView:overlayView];
    
        [self.view addSubview:self.picker.view];
    

    [[UIBarButtonItem alloc] ... action:@selector(takePicture)],

    - (void)takePicture
    {
        [self.picker takePicture]; // triggers didFinishPickingMediaWithInfo
    }
    

    UIImagePickerControllerDelegate

    - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
    {
        UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
        if (image != nil)
        {
            UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
        }
    }