iphone - uiimagepickercontrollerdelegate - UIImagePicker permite la edición atascada en el centro
uiimagepickercontrollerdelegate swift 4 (5)
Tengo un UIImagePicker que funciona perfecto para un tipo de UIImagePickerControllerSourceTypePhotoLibrary, pero cuando uso UIImagePickerControllerSourceTypeCamera, el cuadro de edición no se puede mover desde el centro de la imagen. Entonces, si la imagen es más alta que ancha, el usuario no puede mover el cuadro de edición al recuadro superior de la imagen.
Alguien sabe por qué este sería el caso? Solo ocurre cuando la fuente proviene de la cámara, no de la biblioteca.
Editar: ¡Algunos CÓDIGO!
if (actionSheet.tag == 2) {
if (buttonIndex == 0) { // Camera
// Check for camera
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera] == YES) {
// Create image picker controller
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
// Set source to the camera
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePicker.allowsEditing = YES;
// Delegate is self
imagePicker.delegate = self;
// Show image picker
[self presentViewController:imagePicker
animated:YES
completion:^(void) {
}];
}
}
else if (buttonIndex == 1) { // Photo Library
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary] == YES) {
// Create image picker controller
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
// Set source to the camera
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imagePicker.allowsEditing = YES;
// Delegate is self
imagePicker.delegate = self;
// Show image picker
[self presentViewController:imagePicker
animated:YES
completion:^(void) {
}];
}
}
Como puede ver, los visualizo exactamente igual, pero la edición de la cámara actúa de manera diferente a la edición de la biblioteca de fotos.
Este es el comportamiento predeterminado del controlador de selector de imagen, no puede cambiarlo. La única otra opción es crear su propia utilidad de recorte. Mira el siguiente enlace para ver un ejemplo:
Lo sé, esta no es una buena solución, pero funciona.
Probé en iOS8 + iPhone5, iOS9 + iPhone6sPlus, iOS10 + iPhone6, iOS10 + iPhone6sPlus.
PRECAUCIÓN : PLImageScrollView
y PLCropOverlayCropView
son clases PLCropOverlayCropView
.
- (void)showImagePickerControllerWithSourceType:(UIImagePickerControllerSourceType)sourceType {
UIImagePickerController *imagePickerController = [UIImagePickerController new];
imagePickerController.sourceType = sourceType;
imagePickerController.mediaTypes = @[(NSString *)kUTTypeImage];
imagePickerController.allowsEditing = YES;
imagePickerController.delegate = self;
[self presentViewController:imagePickerController animated:YES completion:^{
[self fxxxImagePickerController:imagePickerController];
}];
}
- (void)fxxxImagePickerController:(UIImagePickerController *)imagePickerController {
if (!imagePickerController
|| !imagePickerController.allowsEditing
|| imagePickerController.sourceType != UIImagePickerControllerSourceTypeCamera) {
return;
}
// !!!: UNDOCUMENTED CLASS
Class ScrollViewClass = NSClassFromString(@"PLImageScrollView");
Class CropViewClass = NSClassFromString(@"PLCropOverlayCropView");
[imagePickerController.view eachSubview:^BOOL(UIView *subview, NSInteger depth) {
if ([subview isKindOfClass:CropViewClass]) {
// 0. crop rect position
subview.frame = subview.superview.bounds;
}
else if ([subview isKindOfClass:[UIScrollView class]]
&& [subview isKindOfClass:ScrollViewClass]) {
BOOL isNewImageScrollView = !self->_imageScrollView;
self->_imageScrollView = (UIScrollView *)subview;
// 1. enable scrolling
CGSize size = self->_imageScrollView.frame.size;
CGFloat inset = ABS(size.width - size.height) / 2;
self->_imageScrollView.contentInset = UIEdgeInsetsMake(inset, 0, inset, 0);
// 2. centering image by default
if (isNewImageScrollView) {
CGSize contentSize = self->_imageScrollView.contentSize;
if (contentSize.height > contentSize.width) {
CGFloat offset = round((contentSize.height - contentSize.width) / 2 - inset);
self->_imageScrollView.contentOffset = CGPointMake(self->_imageScrollView.contentOffset.x, offset);
}
}
}
return YES;
}];
// prevent re-layout, maybe not necessary
@weakify(self, imagePickerController);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
@strongify(self, imagePickerController);
[self fxxxImagePickerController:imagePickerController];
});
}
EDITAR : El método eachSubview:
atraviesa todo el árbol de subvistas.
Parece que este comportamiento es solo un error en iOS 6 ... Básicamente no puedes mover el cuadro de edición, siempre rebota en el medio a menos que acerques un poco. Espero que arreglen eso pronto.
Si ha configurado "Ver apariencia de la barra de estado basada en el controlador" en NO en info.plist y configura la apariencia de la barra de estado como luz usando
UIApplication.shared.statusBarStyle = .lightContent
o usando cualquier otro método, entonces simplemente configure el estilo como .default antes de presentar el selector de imágenes. por ejemplo:
imagePicker.allowsEditing = true
imagePicker.sourceType = .photoLibrary
UIApplication.shared.statusBarStyle = .default
present(imagePicker, animated: true, completion: nil)
Cambia el tipo de fuente de acuerdo a tus necesidades como photoLibrary o camera y en el bloque de finalización de tu didFinishPickingMediaWithInfo agrega lo siguiente al bloque de finalización.
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
//let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage
var pickedImage : UIImage?
if let img = info[UIImagePickerControllerEditedImage] as? UIImage
{
pickedImage = img
}
else if let img = info[UIImagePickerControllerOriginalImage] as? UIImage
{
pickedImage = img
}
dismiss(animated: true, completion: {
UIApplication.shared.statusBarStyle = .lightContent
})}
Aparentemente esta es una solución para lo mismo. Espero que esto ayude.
Una solución que lo resolvió es agregar una entrada en info.plist con " Ver apariencia de la barra de estado basada en el controlador " establecida en NO