Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIImagePicker allowsEditing stuck in center

I have a UIImagePicker that works perfect for a type of UIImagePickerControllerSourceTypePhotoLibrary, but when I use UIImagePickerControllerSourceTypeCamera, the editing box cannot move from the center of the image. So if the image is say taller than it is wide, the user cannot move the editing box to the top square of the image.

Anyone know why this would be the case? It only happens when the source is from the camera, not the library.

Edit: Some CODE!!!

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

So as you can see, I display them the exact same, but the camera edit acts differently than the photo library edit.

like image 446
Eric Avatar asked Sep 27 '12 21:09

Eric


3 Answers

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.

like image 87
Eric Avatar answered Nov 03 '22 10:11

Eric


Thanks yycking. This extension works. Except I added the method call inside viewDidLayoutSubviews so that I don't have to call it every time I want to open image picker.

Here's the full extenstion

extension UIImagePickerController {
    open override var childForStatusBarHidden: UIViewController? {
        return nil
    }

    open override var prefersStatusBarHidden: Bool {
        return true
    }
    
    open override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        fixCannotMoveEditingBox()
    }
    
    func fixCannotMoveEditingBox() {
            if let cropView = cropView,
               let scrollView = scrollView,
               scrollView.contentOffset.y == 0 {
                
                var top: CGFloat = 0.0
                if #available(iOS 11.0, *) {
                    top = cropView.frame.minY + self.view.safeAreaInsets.top
                } else {
                    // Fallback on earlier versions
                    top = cropView.frame.minY
                }
                let bottom = scrollView.frame.height - cropView.frame.height - top
                scrollView.contentInset = UIEdgeInsets(top: top, left: 0, bottom: bottom, right: 0)
                
                var offset: CGFloat = 0
                if scrollView.contentSize.height > scrollView.contentSize.width {
                    offset = 0.5 * (scrollView.contentSize.height - scrollView.contentSize.width)
                }
                scrollView.contentOffset = CGPoint(x: 0, y: -top + offset)
            }
            
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in
                self?.fixCannotMoveEditingBox()
            }
        }
        
        var cropView: UIView? {
            return findCropView(from: self.view)
        }
        
        var scrollView: UIScrollView? {
            return findScrollView(from: self.view)
        }
        
        func findCropView(from view: UIView) -> UIView? {
            let width = UIScreen.main.bounds.width
            let size = view.bounds.size
            if width == size.height, width == size.height {
                return view
            }
            for view in view.subviews {
                if let cropView = findCropView(from: view) {
                    return cropView
                }
            }
            return nil
        }
        
        func findScrollView(from view: UIView) -> UIScrollView? {
            if let scrollView = view as? UIScrollView {
                return scrollView
            }
            for view in view.subviews {
                if let scrollView = findScrollView(from: view) {
                    return scrollView
                }
            }
            return nil
        }
}
like image 22
Raj D Avatar answered Nov 03 '22 08:11

Raj D


Reset contentInset of scrollview:

extension UIImagePickerController {
    func fixCannotMoveEditingBox() {
        if let cropView = cropView,
           let scrollView = scrollView,
           scrollView.contentOffset.y == 0 {
            
            let top = cropView.frame.minY + self.view.safeAreaInsets.top
            let bottom = scrollView.frame.height - cropView.frame.height - top
            scrollView.contentInset = UIEdgeInsets(top: top, left: 0, bottom: bottom, right: 0)
            
            var offset: CGFloat = 0
            if scrollView.contentSize.height > scrollView.contentSize.width {
                offset = 0.5 * (scrollView.contentSize.height - scrollView.contentSize.width)
            }
            scrollView.contentOffset = CGPoint(x: 0, y: -top + offset)
        }
        
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in
            self?.fixCannotMoveEditingBox()
        }
    }
    
    var cropView: UIView? {
        return findCropView(from: self.view)
    }
    
    var scrollView: UIScrollView? {
        return findScrollView(from: self.view)
    }
    
    func findCropView(from view: UIView) -> UIView? {
        let width = UIScreen.main.bounds.width
        let size = view.bounds.size
        if width == size.height, width == size.height {
            return view
        }
        for view in view.subviews {
            if let cropView = findCropView(from: view) {
                return cropView
            }
        }
        return nil
    }
    
    func findScrollView(from view: UIView) -> UIScrollView? {
        if let scrollView = view as? UIScrollView {
            return scrollView
        }
        for view in view.subviews {
            if let scrollView = findScrollView(from: view) {
                return scrollView
            }
        }
        return nil
    }
}

then call it

imagePickercontroller.fixCannotMoveEditingBox()
like image 1
yycking Avatar answered Nov 03 '22 10:11

yycking