UIImagePicker allowsEditing stuck in center

后端 未结 6 1884
后悔当初
后悔当初 2020-11-29 02:47

I have a UIImagePicker that works perfect for a type of UIImagePickerControllerSourceTypePhotoLibrary, but when I use UIImagePickerControllerSourceTypeCamera, the editing bo

相关标签:
6条回答
  • 2020-11-29 03:12

    If you have set "View controller-based status bar appearance" to NO in info.plist and set status bar appearance as light using

     UIApplication.shared.statusBarStyle = .lightContent
    

    or using any other method , Then simply set the style as .default before presenting the image picker. for Eg:

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

    Change the source type according to your need either as photoLibrary or camera and in completion block of your didFinishPickingMediaWithInfo add the following to completion block.

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

    Apparently this is a workaround for the same.Hope this helps.

    0 讨论(0)
  • 2020-11-29 03:14

    I know, this is not a good solution, but it works.

    I tested on iOS8+iPhone5, iOS9+iPhone6sPlus, iOS10+iPhone6, iOS10+iPhone6sPlus.

    CAUTION: PLImageScrollView and PLCropOverlayCropView are UNDOCUMENTED classes.

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

    EDIT: The eachSubview: method traverses all the subviews tree.

    0 讨论(0)
  • 2020-11-29 03:23

    Looks like this behavior is just a bug in iOS 6... Basically you cannot move the editing box, it always bounces back to the middle unless you zoom in a bit. Hopefully they fix that soon.

    0 讨论(0)
  • 2020-11-29 03:29

    This is the default behavior the Image Picker Controller, you can not change it. The only other option is to create your own cropping utility. Check out the link below for an example:

    https://github.com/ardalahmet/SSPhotoCropperViewController

    0 讨论(0)
  • 2020-11-29 03:32

    Stupid answer
    Reset contentInset of scrollview

    #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
    

    then call it

    [imagePickerController fixCannotMoveEditingBox];
    
    0 讨论(0)
  • 2020-11-29 03:34

    A workaround that solved it is to add an entry in info.plist with "View controller-based status bar appearance" set to NO

    0 讨论(0)
提交回复
热议问题