UIImagePicker允许编辑卡在中心

时间:2012-09-27 21:16:43

标签: iphone ios uiimagepickercontroller

我有一个UIImagePicker适用于某种类型的UIImagePickerControllerSourceTypePhotoLibrary,但是当我使用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) {
                                 }];
            }
}

正如您所看到的,我显示它们完全相同,但相机编辑的行为与照片库编辑不同。

6 个答案:

答案 0 :(得分:50)

看起来这种行为只是iOS 6中的一个错误...基本上你无法移动编辑框,除非你放大一点,它总是会反弹到中间。希望他们很快能解决这个问题。

答案 1 :(得分:2)

谢谢yycking。这 extension 有效。除了我在 viewDidLayoutSubviews 中添加了方法调用,这样我就不必每次打开图像选择器时都调用它。

这是完整的扩展

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

答案 2 :(得分:0)

这是Image Picker Controller的默认行为,您无法更改它。唯一的另一种选择是创建自己的裁剪实用程序。请查看以下链接以获取示例:

https://github.com/ardalahmet/SSPhotoCropperViewController

答案 3 :(得分:0)

如果已在info.plist中将“基于视图控制器的状态栏外观”设置为“否”,并使用来将状态栏外观设置为浅色

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

显然,这是解决该问题的方法。希望这会有所帮助。

答案 4 :(得分:-1)

解决此问题的解决方法是在info.plist中添加一个条目,其中“基于控制器的状态栏状态栏外观”设置为NO

答案 5 :(得分:-1)

愚蠢的答案
重置contentInset的滚动视图

<h2>OUTSIDE MAT FORM FIELD</h2>
            <app-state-selector
                        name="people2"
                        [ngModel]="peopleList2"
                        #peopleRef2="ngModel"
                        required
                        maxlength=5
                ></app-state-selector>
                <div class="matFormFieldUnderline" [style.background-color]="peopleRef2.errors ? 'red' : null"></div>
                <div fxLayout>
                  <div fxFlex="70">
                   <mat-hint *ngIf="!peopleRef2.errors?.rows">Valid component: {{ peopleRef2.valid }}</mat-hint>
                   <mat-error *ngIf="peopleRef2.errors?.rows">Valid component: {{ peopleRef2.valid }}</mat-error>
                  </div>
                  <div fxFlex="30" fxLayoutAlign="end"> 
                    <mat-hint>{{peopleRef2.value?.length || 0}} rows</mat-hint>
                  </div>
                </div>  
                <mat-error *ngIf="peopleRef2.errors?.required">required</mat-error>
                <mat-error *ngIf="peopleRef2.errors?.maxlength">max 5 rows</mat-error>

然后称呼

#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