React-native-image-crop-picker: reports] Main Thread Checker: UI API called on a background thread: -[UIViewController init]

Created on 8 Feb 2020  路  6Comments  路  Source: ivpusic/react-native-image-crop-picker

reports] Main Thread Checker: UI API called on a background thread: -[UIViewController init]

When you call ImagePicker.openCropper directly, you will find that the ui thread pauses for 4-5 seconds before you can continue the operation.
Can you take a look

Most helpful comment

The way I fixed it on my implementation was to go to Pods > Development Pods > RNImageCropPicker > ImageCropPicker.m

Then, search for the startCropping method...

(void)startCropping:(UIImage *)image {

The current version has a dispatch_async call around the presentViewController:imageCropVC call. I set the entire call within the dispatch_async. So I changed this...

LabeledCropView *imageCropVC = [[LabeledCropView alloc] initWithImage:image];
    if ([[[self options] objectForKey:@"cropperCircleOverlay"] boolValue]) {
        imageCropVC.cropMode = RSKImageCropModeCircle;
    } else {
        imageCropVC.cropMode = RSKImageCropModeCustom;
    }
    imageCropVC.toolbarTitle = [[self options] objectForKey:@"cropperToolbarTitle"];
    imageCropVC.avoidEmptySpaceAroundImage = [[[self options] objectForKey:@"avoidEmptySpaceAroundImage"] boolValue];
    imageCropVC.dataSource = self;
    imageCropVC.delegate = self;
    NSString *cropperCancelText = [self.options objectForKey:@"cropperCancelText"];
    NSString *cropperChooseText = [self.options objectForKey:@"cropperChooseText"];
    [imageCropVC setModalPresentationStyle:UIModalPresentationCustom];
    [imageCropVC setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
    [imageCropVC.cancelButton setTitle:cropperCancelText forState:UIControlStateNormal];
    [imageCropVC.chooseButton setTitle:cropperChooseText forState:UIControlStateNormal];
    dispatch_async(dispatch_get_main_queue(), ^{
        [[self getRootVC] presentViewController:imageCropVC animated:YES completion:nil];
    });

to

    dispatch_async(dispatch_get_main_queue(), ^{
        LabeledCropView *imageCropVC = [[LabeledCropView alloc] initWithImage:image];
        if ([[[self options] objectForKey:@"cropperCircleOverlay"] boolValue]) {
            imageCropVC.cropMode = RSKImageCropModeCircle;
        } else {
            imageCropVC.cropMode = RSKImageCropModeCustom;
        }
        imageCropVC.toolbarTitle = [[self options] objectForKey:@"cropperToolbarTitle"];
        imageCropVC.avoidEmptySpaceAroundImage = [[[self options] objectForKey:@"avoidEmptySpaceAroundImage"] boolValue];
        imageCropVC.dataSource = self;
        imageCropVC.delegate = self;
        NSString *cropperCancelText = [self.options objectForKey:@"cropperCancelText"];
        NSString *cropperChooseText = [self.options objectForKey:@"cropperChooseText"];
        [imageCropVC setModalPresentationStyle:UIModalPresentationCustom];
        [imageCropVC setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
        [imageCropVC.cancelButton setTitle:cropperCancelText forState:UIControlStateNormal];
        [imageCropVC.chooseButton setTitle:cropperChooseText forState:UIControlStateNormal];

        [[self getRootVC] presentViewController:imageCropVC animated:YES completion:nil];
    });

The important part is the dispatch_async(dispatch_get_main_queue(), ^{ call that was moved from right above the presentViewControlller:imageCropVC call to the first line of the method.

All 6 comments

It's just a temporary iOS fix.

Open Xcode --> pods --> Development Pods --> RNImageCropPicker --> ImageCropPicker.m

In this method
(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info

Present code:

 [picker dismissViewControllerAnimated:YES completion:[self waitAnimationEnd:^{

                       self.resolve(video);
       }]];

Updated code: (Keep the above code in dispatch_async)
dispatch_async(dispatch_get_main_queue(), ^{ [picker dismissViewControllerAnimated:YES completion:[self waitAnimationEnd:^{ self.resolve(video); }]]; });

Same problem here

@dileepkantapop your fix stand for video right, i facing issue when open openCropper to crop an image. How can fix it.

The way I fixed it on my implementation was to go to Pods > Development Pods > RNImageCropPicker > ImageCropPicker.m

Then, search for the startCropping method...

(void)startCropping:(UIImage *)image {

The current version has a dispatch_async call around the presentViewController:imageCropVC call. I set the entire call within the dispatch_async. So I changed this...

LabeledCropView *imageCropVC = [[LabeledCropView alloc] initWithImage:image];
    if ([[[self options] objectForKey:@"cropperCircleOverlay"] boolValue]) {
        imageCropVC.cropMode = RSKImageCropModeCircle;
    } else {
        imageCropVC.cropMode = RSKImageCropModeCustom;
    }
    imageCropVC.toolbarTitle = [[self options] objectForKey:@"cropperToolbarTitle"];
    imageCropVC.avoidEmptySpaceAroundImage = [[[self options] objectForKey:@"avoidEmptySpaceAroundImage"] boolValue];
    imageCropVC.dataSource = self;
    imageCropVC.delegate = self;
    NSString *cropperCancelText = [self.options objectForKey:@"cropperCancelText"];
    NSString *cropperChooseText = [self.options objectForKey:@"cropperChooseText"];
    [imageCropVC setModalPresentationStyle:UIModalPresentationCustom];
    [imageCropVC setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
    [imageCropVC.cancelButton setTitle:cropperCancelText forState:UIControlStateNormal];
    [imageCropVC.chooseButton setTitle:cropperChooseText forState:UIControlStateNormal];
    dispatch_async(dispatch_get_main_queue(), ^{
        [[self getRootVC] presentViewController:imageCropVC animated:YES completion:nil];
    });

to

    dispatch_async(dispatch_get_main_queue(), ^{
        LabeledCropView *imageCropVC = [[LabeledCropView alloc] initWithImage:image];
        if ([[[self options] objectForKey:@"cropperCircleOverlay"] boolValue]) {
            imageCropVC.cropMode = RSKImageCropModeCircle;
        } else {
            imageCropVC.cropMode = RSKImageCropModeCustom;
        }
        imageCropVC.toolbarTitle = [[self options] objectForKey:@"cropperToolbarTitle"];
        imageCropVC.avoidEmptySpaceAroundImage = [[[self options] objectForKey:@"avoidEmptySpaceAroundImage"] boolValue];
        imageCropVC.dataSource = self;
        imageCropVC.delegate = self;
        NSString *cropperCancelText = [self.options objectForKey:@"cropperCancelText"];
        NSString *cropperChooseText = [self.options objectForKey:@"cropperChooseText"];
        [imageCropVC setModalPresentationStyle:UIModalPresentationCustom];
        [imageCropVC setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
        [imageCropVC.cancelButton setTitle:cropperCancelText forState:UIControlStateNormal];
        [imageCropVC.chooseButton setTitle:cropperChooseText forState:UIControlStateNormal];

        [[self getRootVC] presentViewController:imageCropVC animated:YES completion:nil];
    });

The important part is the dispatch_async(dispatch_get_main_queue(), ^{ call that was moved from right above the presentViewControlller:imageCropVC call to the first line of the method.

leelandclay's suggestion fixed the issue for me, I'd suggest this gets implemented

The way I fixed it on my implementation was to go to Pods > Development Pods > RNImageCropPicker > ImageCropPicker.m

Then, search for the startCropping method...

(void)startCropping:(UIImage *)image {

The current version has a dispatch_async call around the presentViewController:imageCropVC call. I set the entire call within the dispatch_async. So I changed this...

LabeledCropView *imageCropVC = [[LabeledCropView alloc] initWithImage:image];
    if ([[[self options] objectForKey:@"cropperCircleOverlay"] boolValue]) {
        imageCropVC.cropMode = RSKImageCropModeCircle;
    } else {
        imageCropVC.cropMode = RSKImageCropModeCustom;
    }
    imageCropVC.toolbarTitle = [[self options] objectForKey:@"cropperToolbarTitle"];
    imageCropVC.avoidEmptySpaceAroundImage = [[[self options] objectForKey:@"avoidEmptySpaceAroundImage"] boolValue];
    imageCropVC.dataSource = self;
    imageCropVC.delegate = self;
    NSString *cropperCancelText = [self.options objectForKey:@"cropperCancelText"];
    NSString *cropperChooseText = [self.options objectForKey:@"cropperChooseText"];
    [imageCropVC setModalPresentationStyle:UIModalPresentationCustom];
    [imageCropVC setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
    [imageCropVC.cancelButton setTitle:cropperCancelText forState:UIControlStateNormal];
    [imageCropVC.chooseButton setTitle:cropperChooseText forState:UIControlStateNormal];
    dispatch_async(dispatch_get_main_queue(), ^{
        [[self getRootVC] presentViewController:imageCropVC animated:YES completion:nil];
    });

to

    dispatch_async(dispatch_get_main_queue(), ^{
        LabeledCropView *imageCropVC = [[LabeledCropView alloc] initWithImage:image];
        if ([[[self options] objectForKey:@"cropperCircleOverlay"] boolValue]) {
            imageCropVC.cropMode = RSKImageCropModeCircle;
        } else {
            imageCropVC.cropMode = RSKImageCropModeCustom;
        }
        imageCropVC.toolbarTitle = [[self options] objectForKey:@"cropperToolbarTitle"];
        imageCropVC.avoidEmptySpaceAroundImage = [[[self options] objectForKey:@"avoidEmptySpaceAroundImage"] boolValue];
        imageCropVC.dataSource = self;
        imageCropVC.delegate = self;
        NSString *cropperCancelText = [self.options objectForKey:@"cropperCancelText"];
        NSString *cropperChooseText = [self.options objectForKey:@"cropperChooseText"];
        [imageCropVC setModalPresentationStyle:UIModalPresentationCustom];
        [imageCropVC setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
        [imageCropVC.cancelButton setTitle:cropperCancelText forState:UIControlStateNormal];
        [imageCropVC.chooseButton setTitle:cropperChooseText forState:UIControlStateNormal];

        [[self getRootVC] presentViewController:imageCropVC animated:YES completion:nil];
    });

The important part is the dispatch_async(dispatch_get_main_queue(), ^{ call that was moved from right above the presentViewControlller:imageCropVC call to the first line of the method.

I can't find method "startCropping"

Was this page helpful?
0 / 5 - 0 ratings

Related issues

DISKONEKTeD picture DISKONEKTeD  路  3Comments

Martian2Lee picture Martian2Lee  路  3Comments

althurzard picture althurzard  路  3Comments

zhangjunhou picture zhangjunhou  路  3Comments

co-de picture co-de  路  3Comments