web-dev-qa-db-ja.com

UIImagePickerにより、編集が中央で止まる

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

ご覧のとおり、まったく同じように表示しますが、カメラの編集はフォトライブラリの編集とは動作が異なります。

40
Eric

この動作はiOS6の単なるバグのようです...基本的に編集ボックスを移動することはできません。少しズームインしない限り、常に中央に戻ります。うまくいけば、彼らはすぐにそれを修正します。

52
Eric

Info.plistで「コントローラーベースのステータスバーの外観を表示する」を「いいえ」に設定し、を使用してステータスバーの外観を明るいものとして設定した場合

 UIApplication.shared.statusBarStyle = .lightContent

または他の方法を使用して、画像ピッカーを表示する前に、スタイルを.defaultとして設定するだけです。例:

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

photoLibraryまたはcameraのいずれかとして、必要に応じてソースタイプを変更し、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
    })}

どうやらこれは同じための回避策です。これが役立つことを願っています。

0
ashin asok

これは良い解決策ではありませんが、機能します。

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

[〜#〜] edit [〜#〜]eachSubview:メソッドはすべてのサブビューツリーをトラバースします。

0
iwill

これはイメージピッカーコントローラーのデフォルトの動作であり、変更することはできません。他の唯一のオプションは、独自のトリミングユーティリティを作成することです。例については、以下のリンクを確認してください。

https://github.com/ardalahmet/SSPhotoCropperViewController

0
Vikings

愚かな答え
コンテンツをリセットスクロールビューのインセット

#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];
0
yycking