UIImagePicker allowsEditing停留在中心(UIImagePicker all

2019-06-18 08:57发布

我有一个类型UIImagePickerControllerSourceTypePhotoLibrary作品完美一UIImagePicker,但是当我使用UIImagePickerControllerSourceTypeCamera,编辑框不能从图像的中心移动。 因此,如果图像是说长得比它宽,用户无法编辑框移动到图像的顶部方形。

任何人都知道为什么会这样呢? 它只有当源是从相机,而不是库发生。

编辑:一些代码!

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) {
                                 }];
            }
}

所以你可以看到,我展示他们完全一样的,但相机编辑的作用比照片库编辑不同。

Answer 1:

看起来这种行为只是在iOS 6中的一个错误......基本上你不能移动的编辑框,它总是除非你有点放大反弹到中间。 希望他们很快修复。



Answer 2:

这是默认行为的图片选择器控制器,你不能改变它。 唯一的其他选择是创建自己的裁剪工具。 看看下面的一个例子的链接:

https://github.com/ardalahmet/SSPhotoCropperViewController



Answer 3:

我知道,这不是一个很好的解决方案,但它的工作原理。

我在iOS8上的iPhone5 +,iOS9 + iPhone6sPlus,iOS10 + iPhone6,iOS10 + iPhone6sPlus测试。

注意PLImageScrollViewPLCropOverlayCropView未记录的类。

- (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];
    });
}

编辑eachSubview:方法遍历所有的子视图树。



Answer 4:

如果您在info.plist中设置“查看基于控制器的状态栏外观” NO和使用设置状态栏外观光

 UIApplication.shared.statusBarStyle = .lightContent

或使用任何其他的方法,然后,只需呈现所述图像拾取器之前设置风格.DEFAULT。 对于例如:

imagePicker.allowsEditing = true
imagePicker.sourceType = .photoLibrary
UIApplication.shared.statusBarStyle = .default
present(imagePicker, animated: true, completion: nil)

根据您的需要或作为photoLibrary或相机 ,在你didFinishPickingMediaWithInfo完成块添加以下完成块更改源类型。

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
    })}

显然,这是针对same.Hope这有助于解决办法。



Answer 5:

这解决了它一个解决办法是用“ 查看基于控制器的状态栏外观 ”添加在info.plist中的条目设置为NO



Answer 6:

愚蠢的答案
重置滚动型contentInset

#import <objc/runtime.h>

@interface WeakObjectContainer : NSObject
@property (nonatomic, readonly, weak) id object;
@end

@implementation WeakObjectContainer
- (instancetype) initWithObject:(id)object
{
    if (!(self = [super init]))
        return nil;

    _object = object;

    return self;
}
@end

@implementation UIImagePickerController (PLUS)

// MARK: - Create a weak stored property in extension
- (id)weakObjectForKey:(const void*)key {
    WeakObjectContainer *container = objc_getAssociatedObject(self, key);
    return [container object];
}

- (void)setWeakObject:(id)object forKey:(const void*)key {
    WeakObjectContainer *container = [[WeakObjectContainer alloc] initWithObject:object];
    objc_setAssociatedObject(self, key, container, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

// MARK: - Create a weak property for scrollView
- (UIScrollView *)scrollView {
    return [self weakObjectForKey:_cmd];
}

- (void)setScrollView:(UIScrollView *)scrollView {
    [self setWeakObject:scrollView forKey:@selector(scrollView)];
}

// MARK: - Create a weak property for cropView
- (UIView *)cropView {
    return [self weakObjectForKey:_cmd];
}

- (void)setCropView:(UIView *)cropView {
    [self setWeakObject:cropView forKey:@selector(cropView)];
}

// MARK: - Fix cannot move editing xox
- (void)fixCannotMoveEditingBox {
    if (!self.scrollView || !self.cropView) {
        UIView *view = [self view];
        self.scrollView = [self findScrollView:view];
        self.cropView = [self findCropView:view];

        if (self.scrollView && self.cropView) {
            CGFloat top = self.cropView.frame.origin.y;
            CGFloat bottom = ({
                self.scrollView.frame.size.height - self.cropView.frame.size.height - self.cropView.frame.origin.y;
            });
            self.scrollView.contentInset = UIEdgeInsetsMake(top, 0, bottom, 0);
            self.scrollView.contentOffset = CGPointMake(0, -1);
        }
    }

    __weak typeof(self) weakself = self;
    dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC);
    dispatch_after(delay, dispatch_get_main_queue(), ^(void){
        __strong typeof(weakself) strongself = weakself;
        [strongself fixCannotMoveEditingBox];
    });
}

- (UIScrollView *)findScrollView:(UIView *)view {
    if ([view isKindOfClass:[UIScrollView class]]) {
        return (UIScrollView *)view;
    }
    for (UIView *subview in [view subviews]) {
        UIScrollView *view = [self findScrollView:subview];
        if (view) {
            return view;
        }
    }
    return nil;
}

- (UIView *)findCropView:(UIView *)view {
    CGFloat width = [[UIScreen mainScreen] bounds].size.width;
    CGSize size = [view frame].size;
    if (size.width == width && size.height == width) {
        return view;
    }
    for (UIView *subview in [view subviews]) {
        UIView *view = [self findCropView:subview];
        if (view) {
            return view;
        }
    }
    return nil;
}

@end

然后调用它

[imagePickerController fixCannotMoveEditingBox];


文章来源: UIImagePicker allowsEditing stuck in center