Search code examples
iosobjective-ccocoa-touchuiimagepickercontrolleruiswipegesturerecognizer

Place Swipe Gesture over UIImagePickerController


I'm wanting to be able to swipe right when using the video camera to hide the camera controls. The view presents just fine but when I swipe I get an error.

I'm getting the following error:

VideoStream[13065:60b] -[UILayoutContainerView toggleControlsWithGesture]: unrecognized selector sent to instance 0x1701a1960 2014-04-26 11:37:28.639 VideoStream[13065:60b] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UILayoutContainerView toggleControlsWithGesture]:

Here is the code:

- (BOOL)startCameraControllerFromViewController:(UIViewController *)controller usingDelegate:(id)delegate
{
    if (([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera] == NO)
        || (delegate == nil)
        || (controller == nil)) {
        return NO;
    }

    _cameraUI = [[UIImagePickerController alloc] init];
    _cameraUI.sourceType = UIImagePickerControllerSourceTypeCamera;
    _cameraUI.mediaTypes = [[NSArray alloc] initWithObjects:(NSString *)kUTTypeMovie, nil];
    _cameraUI.allowsEditing = NO;
    _cameraUI.delegate = delegate;

    [controller presentViewController:_cameraUI animated:YES completion:nil];
    UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] 
                                            initWithTarget:_cameraUI.view 
                                                    action:@selector(toggleControlsWithGesture)];
    swipeRight.delegate = self;

    //And assuming the "Up" direction in your screenshot is no accident
    swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
    [_cameraUI.view addGestureRecognizer:swipeRight];

    return YES;
}

This is the swipe code:

- (void)toggleControlsWithGesture
{
    NSLog(@"BOOM");
    if (_showsControls == YES) {
        _cameraUI.showsCameraControls = NO;
    } else {
        _cameraUI.showsCameraControls = YES;
    }
}

Any help that can be offered is GREAT appreciated.


Solution

  • Instead of:

    UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc]
                                            initWithTarget:_cameraUI.view 
                                                    action:@selector(toggleControlsWithGesture)];
    

    do:

    UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc]
                                            initWithTarget:self
                                                    action:@selector(toggleControlsWithGesture)];
    

    Explanation:

    For your UISwipeGestureRecognizer object, you are currently doing -initWithTarget:_cameraUI.view.

    This means the target that will respond to the specified action method will be _cameraUI.view but _cameraUI.view does not provide any -toggleControlsWithGesture method and hence the error.
    The -toggleControlsWithGesture method will be found in this class and so you will need to specify the target as self.


    Example: Consider in XYZClass.m, we do something like:

    ABCClass *abcObject = [ABCClass alloc] init];
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
                                   initWithTarget:abcObject 
                                           action:@selector(doSomething)];
    

    This basically says that the abcObject will respond to the event by firing a doSomething method.
    But... for this to happen, ABCClass should have defined the doSomething method.

    In your case, _cameraUI is of UIImagePickerController class and it's view may be a property or another class object. In either case, it does not have the -toggleControlsWithGesture method which you created for your purposes.