UIImagePickerController 在缩放时显示黑条 – 这是 iOS 中的错误吗?
UIImagePickerController shows black bar when zooming – Is this a bug in iOS?
编辑:有人建议这个 post 是 duplicate,但事实并非如此,因为黑条是最初不存在仿射变换无法解决问题。
我 运行 在 iPad Air 2 和目标 iOS 8 上。
我有一个 UIImagePickerController
,其 showsCameraControls
属性 设置为 NO
。在横向启动应用程序然后放大时,会发生这种情况(所有图像均未裁剪):
出现黑条,可以通过将设备方向更改为纵向(也会显示黑条)然后再将其改回来消除黑条。
更改为纵向后:
返回横向(+ 放大):
奇怪的是,返回横向后,缩放滑块在缩放过程中不再可见。最初从纵向开始时,缩放首先起作用,直到变为横向,此时会出现一个黑条,返回纵向时会保留。
None 将 showsCameraControls
设置为 YES
时会发生这种情况。
我怎样才能摆脱这个问题?
更新:Apple 声称已在 iOS 9.
中修复此问题
我找到了一种方法来解决我由于缺乏更好的理解而标记为错误的问题(苹果提供的样本也会发生这种情况)。
我的解决方案是通过向叠加视图添加 UIPinchGestureRecognizer
来进行手动缩放。然后控制器必须实现缩放回调,以消除上述现象。
@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
编辑:有人建议这个 post 是 duplicate,但事实并非如此,因为黑条是最初不存在仿射变换无法解决问题。
我 运行 在 iPad Air 2 和目标 iOS 8 上。
我有一个 UIImagePickerController
,其 showsCameraControls
属性 设置为 NO
。在横向启动应用程序然后放大时,会发生这种情况(所有图像均未裁剪):
出现黑条,可以通过将设备方向更改为纵向(也会显示黑条)然后再将其改回来消除黑条。
更改为纵向后:
返回横向(+ 放大):
奇怪的是,返回横向后,缩放滑块在缩放过程中不再可见。最初从纵向开始时,缩放首先起作用,直到变为横向,此时会出现一个黑条,返回纵向时会保留。
None 将 showsCameraControls
设置为 YES
时会发生这种情况。
我怎样才能摆脱这个问题?
更新:Apple 声称已在 iOS 9.
中修复此问题我找到了一种方法来解决我由于缺乏更好的理解而标记为错误的问题(苹果提供的样本也会发生这种情况)。
我的解决方案是通过向叠加视图添加 UIPinchGestureRecognizer
来进行手动缩放。然后控制器必须实现缩放回调,以消除上述现象。
@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