0

I'm fairly new to Objective-C and I'm trying to get a button pressed event to trigger on a button that is on a custom view that is being overlaid on a UIImagePicker. I connect the button to an IBAction on the overlaid view, but when I press the button I get a bad access error.

here is the code I am using to for the overlay:

// prepare imagePicker view
    UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
    imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
    imagePicker.delegate = self;
    imagePicker.allowsEditing = NO;
    imagePicker.showsCameraControls = NO;

    // create view for overlay
    CGRect overlayRect = CGRectMake(0, 0, imagePicker.view.frame.size.width, imagePicker.view.frame.size.height);
    UIView *overlayView = [[UIView alloc] initWithFrame:overlayRect];

    // prepare custom view
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:
                                @"Main" bundle:[NSBundle mainBundle]];

    UIViewController *overlay = [storyboard instantiateViewControllerWithIdentifier:@"overlayView"];

    imagePicker.cameraOverlayView = overlay.view;

    // display imagePicker
    [self.navigationController presentViewController:imagePicker animated:YES completion:nil];
Dan
  • 1
  • 1
  • Could you please show the code for the button? How is it connected to the IBAction method? – Armin Jan 25 '15 at 18:34
  • I have connected it to the overlay view controller with ctrl+drag and created an IBAction – Dan Jan 25 '15 at 19:03
  • - (IBAction)testButton:(id)sender { _testLabel.text = @"text has changed"; } – Dan Jan 25 '15 at 19:04
  • Oh I see where the problem is. The `overlayView` has to be just a view, not a viewController. You can load a nib file for the view, and then set the `cameraOverlayView` property to be that view. Here's documentation for that: https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UIImagePickerController_Class/index.html#//apple_ref/occ/instp/UIImagePickerController/cameraOverlayView – Armin Jan 25 '15 at 19:10
  • If you look at the link I provided in my answer, you'll see how it should be implemented. Also, if my response resolves your problem, please mark it as the correct answer. – Armin Jan 25 '15 at 19:11
  • btw, I just noticed that you're not even using the `overlayView` after creating it. You should remove that from your code if it's doing nothing. – Armin Jan 25 '15 at 19:16
  • again, thank you so much for the quick response. I see, so buttons and actions cannot be accessed from the overlay, it is just used to present. so if there was something in the overlay that I wanted to change dynamically, I would have to set the action from the presenting view controller? for example it I wanted to change a label.text – Dan Jan 25 '15 at 19:25
  • You could hold a reference to the `overlayView` in the presenting viewController, so you can access its properties. Just make sure that you set it to nil when dismissing the `imagePicker` so it doesn't stay in memory. – Armin Jan 25 '15 at 19:40
  • by adding a reference do you mean: overlayView *overlay = [[overlayView alloc]init] and accessing the label: overlay.testLabel.text = @"some text"? I have been trying this and that doesn't seem to be working for me – Dan Jan 25 '15 at 20:06
  • im not exactly sure why, but placing the reference at the bottom after displaying the image picker works. and calling the function from the overlay controller to change the text dynamically works as well. thank you for your help – Dan Jan 25 '15 at 20:26

2 Answers2

0

can you try to make UIImagePickerController *imagePicker as a property

@property (nonatomic) UIImagePickerController *imagePicker;

then

self.imagePicker = [[UIImagePickerController alloc] init];
self.imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
self.imagePicker.delegate = self;
self.imagePicker.allowsEditing = NO;
self.imagePicker.showsCameraControls = NO;

Good luck

Mustafa Ibrahim
  • 1,110
  • 1
  • 9
  • 17
0

You should have the buttons point to a method on the presenting viewController. Maybe adding the overlay as a childViewController to the imagePicker would solve your problem, but the cameraOverlayView should be just a view.

Here's a good implementation of what you're trying to do: Using cameraOverlayView with UIImagePickerController


UPDATE: Keep a weak reference to overlayView from your presenting View Controller through a property such as:

@property (weak) OverlayView *overlayView;

and in your code:

    // create view for overlay
    CGRect overlayRect = CGRectMake(0, 0, imagePicker.view.frame.size.width, imagePicker.view.frame.size.height);
    imagePicker.cameraOverlayView = [[OverlayView alloc] initWithFrame:overlayRect];

    // Hold a weak reference to the `cameraOverlayView`
    self.overlayView = (OverlayView *)imagePicker.cameraOverlayView;

now the presenting viewController can access self.overlayView's public properties when the imagePicker is alive. Make sure you check if self.overlayView before trying to access its properties.

Community
  • 1
  • 1
Armin
  • 1,150
  • 8
  • 24
  • Hi, Thank you again for all your help. I just tried the updated code and I get an error "no visible interface for 'overlayviewcontrolloer' declares the selector 'alloc' and another error on where to hold a weak reference that says "expected expression" – Dan Jan 27 '15 at 17:32
  • Did you creat the new OverlayView class? It's a UIView, not a UIViewController! If you're loading it from a xib file, the init line should be different. If not you have to override 'initWithFrame:' to add your subviews and buttons. – Armin Jan 27 '15 at 17:56
  • I see, yes I was using a UIViewController with "[[overlayViewController alloc] initWithNibName:@"overlayViewController" bundle:nil];" but if I use the overlay view controller I can't use the init with frame? since its different? so I would have to use the UIView to add any custom buttons? – Dan Jan 27 '15 at 23:34
  • Well you could try adding your viewController as a `childViewController` to imagePicker, and THEN setting its `cameraOverlayView` to your VC's view and see if that works. My suspicion is that the view controller gets released since nothing is holding a reference to it, but the view remains since `imagePicker` is holding a reference to the view. – Armin Jan 28 '15 at 00:49