2

Edit: It has been suggested this post is a duplicate, which is not the case as the black bars are not initially present an an affine transformation does not remedy the problem.

I run this on an iPad Air 2 and target iOS 8. I have a UIImagePickerController whose showsCameraControls property is set to NO. When starting the app in landscape and then zooming in, this is what happens (all images are non-cropped):

enter image description here

A black bar appears and can be gotten rid of by changing device orientation to portrait (which will also show the black bar) and then changing it back.

After change to portrait:

enter image description here

Back to landscape (+ zooming in):

enter image description here

Strangely, after returning to landscape, the zoom slider is not visible anymore during zooming. When starting from portrait initially, zooming first works until one changes to landscape, where a black bar appears, which stays when going back to portrait.

None of this happens when setting showsCameraControls to YES. How can I get rid of this issue?

UPDATE: Apple claims to have fixed this in iOS 9.

Community
  • 1
  • 1
oarfish
  • 4,116
  • 4
  • 37
  • 66
  • possible duplicate of [UIImagePickerController doesn't fill screen](http://stackoverflow.com/questions/2674375/uiimagepickercontroller-doesnt-fill-screen) – tbaranes May 17 '15 at 16:16
  • @Ckouta No, the problems seem to be different: In my case, the bar appears only after zooming. Also, modifying `cameraViewTransform` only affects the non-black part in the view, the black bar stays where it is. – oarfish May 17 '15 at 16:21

1 Answers1

4

I have found one way to work around what I for lack of better understanding would label a bug (as it happens with apple-provided samples as well).

The solution for me is to do manual zooming, by adding a UIPinchGestureRecognizer to the overlay view. The Controller must then implement a zooming callback which will get rid of the phenomenon described above.

@implementation CameraViewController
{
    CGFloat _lastScale; //< the current zoom scale before update
}

- (void)viewDidLoad
{
    [super viewDidLoad];

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

    [[NSBundle mainBundle] loadNibNamed:@"CameraOverlay" owner:self options:nil];

    UIPinchGestureRecognizer *pinchRec = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(zoom:)];
    [self.overlayView addGestureRecognizer:pinchRec];

    self.imagePicker.cameraOverlayView = self.overlayView;  
    _lastScale = 1.;
}

- (void)zoom:(UIPinchGestureRecognizer *) sender
{
    // reset scale when pinch has ended so that future scalings are applied cumulatively and the zoom does not jump back (not sure I understand this)
    if([sender state] == UIGestureRecognizerStateEnded)
    {
        _lastScale = 1.0;
        return;
    }

    CGFloat scale = 1.0 - (_lastScale - sender.scale); // sender.scale gives current distance of fingers compared to initial distance. We want a value to scale the current transform with, so diff between previous scale and new scale is what must be used to stretch the current transform


    CGAffineTransform currentTransform = self.imagePicker.cameraViewTransform;
    CGAffineTransform newTransform = CGAffineTransformScale (currentTransform, scale, scale); // stretch current transform by amount given by sender

    newTransform.a = MAX(newTransform.a, 1.); // it should be impossible to make preview smaller than screen (or initial size)
    newTransform.d = MAX(newTransform.d, 1.);

    self.imagePicker.cameraViewTransform = newTransform;
    _lastScale = sender.scale;

}
@end
oarfish
  • 4,116
  • 4
  • 37
  • 66
  • 1
    Probably saved me a few hours this morning, thx! By the way this is still happening on iOS 9. – AkademiksQc Jan 14 '16 at 13:18
  • @AkademiksQc Interesting. Apple said they *"believe this issue has been addressed"* in iOS9. I have not tested it yet, but maybe I should and update my bug report. Though I find it strange that they would claim this since it would be obvious whether the bug has been fixed or not. – oarfish Jan 14 '16 at 13:32
  • Yes indeed, i'm actually on 9.1 – AkademiksQc Jan 14 '16 at 15:02
  • 1
    I assumed that the zoom transform was applied to the image provided by the didFinishPickingMediaWithInfo delegate method but seems that its not applied. I attempted to apply it manually with CG but I can't get it to work properly...I am missing something. I was trying to apply a CGContextScaleCTM using imagePicker.cameraOverlayView.transform.a but that does not match the transform on the camera view. Do you have any clues ? thx – AkademiksQc Jan 14 '16 at 20:10
  • @AkademiksQc This was some time ago, so I'm not in it any more, but here's what I did to actually apply the transform, maybe it helps. http://pastebin.com/cmeFiUBj the `cropToSize` method is defined in a category, I'm not sure if it is necessary. http://pastebin.com/iDchYmi3 – oarfish Jan 15 '16 at 08:20
  • Thank you, really appreciate it – AkademiksQc Jan 18 '16 at 15:06