cameraOverlayView prevents editing with allowsEditing - ios

Editing a photo after it's been taken (moving and scaling it) works fine in my app with this line:
[imagePicker setAllowsEditing:YES];
But if I also use a cameraOverlayView, the editing mode doesn't work anymore. The screen comes up, but pan and pinch gestures don't make anything happen.
I'm using your average image picker controller:
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
And I add a camera overlay view, created from a custom view controller's view:
CameraOverlayViewController *overlayController = [[CameraOverlayViewController alloc] init];
UIView *overlayView = overlayController.view;
[imagePicker setCameraOverlayView:overlayView];
In IB, that view is set up to enable user interaction and multiple touch, which allows it to zoom and focus while taking the picture. But once the picture is taken and it enters editing mode, you cannot pan or pinch to move or scale the photo.
What am I missing?

Does your overlay take up the entire space of the camera view? If so, touches are going to the overlay instead of the view below, even if you have a transparent background.
Add this method to your overlay view and it will ignore touches so that they are passed to the views below. (You are overriding a method of UIView that detects touches.)
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
return NO;
}
Note: as well as that fantastic tip, you may also want to use this piece of info, to remove your overlay view, at that stage: UIImagePicker cameraOverlayView appears on Retake screen

Related

iOS camera view - get size of camera area

Is there a way to find out the height of the camera view only(not the picker view)? I need to know so I can centre the cross hairs on my overlay view vertically - screenshot below
As an option - you can create custom camera overlay view with all custom controls on positions you want and then set:
imagePickerController.cameraOverlayView = yourOverlayView;
imagePickerController.showsCameraControls = NO;
Source and more info: in this SO question

Adding UIImagePickerController as a subview

I want to add a UIImagePickerController in a custom frame, so have been following a few posts around adding the UIImagePickerController view as a subview.
A couple of questions:
How would I adjust the frame of this subview?
After adding as a subview, touch seems to be disabled (I can't browse photos or press the cancel button), how would I solve this?
Many thanks in advance!
My Code:
self.imagePicker = [[UIImagePickerController alloc] init];
self.imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
self.imagePicker.delegate = self;
//This is a subview of self.view.
[self.pickerControllerHolderView addSubview:self.imagePicker.view];
// This seems to adjust the size of the view, but squashes the view.
// self.pickerControllerHolderView.transform = CGAffineTransformMakeScale(1, 0.5);
The internals of this class are private and it is not meant to be added as a subview. It is a self contained view controller and navigation controller and will most likely not work how you expect it to. If you need custom UI for picking photos, you should access the ALAssetsLibrary and display the contents yourself.

UIImagePickerController cameraOverlay behind shutter

Can not find any definitive answer, but it looks like it is not possible. I am just displaying a frame image as an overlay to guide the user where the photo should be positioned. However the frame appears on top of the shutter on the opening and closing animation. Is there any (app store compliant) way to make the overlay view appear behind the shutter animation?
Also, when to remove/hide the overlay after the user pressed the take photo button? I have allowsEditing enabled, so I don't want the frame overlay being shown when editing the image. I can not figure how to capture that event.
Thanks
On the iPad this problem doesn't exist, and the overlay view is behind the shutter animation by default. But on the iPhone, the overlay appears at front.
EDIT:
I've found a solution that worked for me.
You have to set your overlay view as a subview in this method:
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
if (!viewController)
return;
UIView* controllerViewHolder = viewController.view;
UIView* controllerCameraView = [[controllerViewHolder subviews] objectAtIndex:0];
UIView* controllerPreview = [[controllerCameraView subviews] objectAtIndex:0];
[controllerCameraView insertSubview:self.overlayView aboveSubview:controllerPreview];
}
Hope it helps
Original source:
http://www.alexcurylo.com/blog/2009/06/18/uiimagepickercontroller-in-3-0/

UIPanGestureRecognizer won't pan right

I have a UIView subclass to which I have added a UIPanGestureRocognizer:
_panGestureRecognizer = [[UIPanGestureRecognizer alloc]
initWithTarget:self action:#selector(handlePanGesture:)];
_panGestureRecognizer.maximumNumberOfTouches = 1;
_panGestureRecognizer.delegate = self;
[self addGestureRecognizer:_panGestureRecognizer];
This view is used in a view hierarchy which includes a UISplitViewController as the top-level view/controller.
When testing this in the iPad simulator in landscape orientation, if I start the pan by going up/down/left, my handlePanGesture: method is called as expected. However, if I start the pan by going right then my handlePanGesture: method is not called. Why not?
While I was writing up this question, I figured out the answer for myself:
The UISplitViewController since iOS 5 will, by default, recognize a swipe gesture to the right and display the popover controller. This is obvious in portrait orientation, however, in landscape orientation, the gesture has no apparent effect because the left-side view displayed as the popover in portrait is always displayed in landscape.
The solution to this is to disable the swipe gesture for the UISplitViewController with:
splitViewController.presentsWithGesture = NO;
I don't know if there is a way to have both gestures work.

Detecting touches with stacked Views & passing Touch events from a UIScrollView

I'm trying to close a pop-up menu if the user selects anywhere EXCEPT with-in the bounds of the pop-up itself. In other words, they select the background, the pop-up closes.
I currently have a RootViewController that loads a UIView with a bunch of other UI Elements.
At one point, a pop-up (custom) menu is rendered - this is a separate UIViewController with associated .xib. Its loaded on the screen by:
SectionsChooserViewController *cv = [[SectionsChooserViewController alloc] initWithNibName:#"SectionsChooserViewController" bundle:[NSBundle mainBundle]];
cv.view.frame = CGRectMake(584, 391, 314, 346);
cv.delegate = self;
This view occupies only a small portion of the screen. So added detect code for touches to this view will only register the callback if you're ON the view.
If I don't handle touches in the "SectionsChooserViewController" and instead implement the touchesBegan in the rootViewController (which loads the "SectionsChooser...") it doesn't get called for 90% of the view because the UIScrollView's that I have seem to register the touch and not pass it on.
Is there a way to make the UIScrollView pass the touch event?
Edit: At least I think the UIScrollView's are taking the touch event. I'm not sure - I have nearly 20 UI Controls on the page.
Edit: Ok, it is the UIScrollView. If I turn off interaction-enabled on both scrollView's the UIView will get the touches, but this breaks the UIScrollViews - so that won't work.
You might be able to use [super touchesBegan:withEvent:] to help solve the problem.
Depending on what your trying to do you might be able to use UIGestureRecognizer to capture the touch events.
UITapGestureRecognizer *doubleTapGestureRecognizer = [[UITapGestureRecognizer alloc]
initWithTarget:self action:#selector(handleDoubleTap:)];
doubleTapGestureRecognizer.numberOfTapsRequired = 2; //change value to 1 for single taps
[self addGestureRecognizer:doubleTapGestureRecognizer];

Resources