问题
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):
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:
Back to landscape (+ zooming in):
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.
回答1:
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
来源:https://stackoverflow.com/questions/30288950/uiimagepickercontroller-shows-black-bar-when-zooming-is-this-a-bug-in-ios