IT TIP

iOS 8에서 UIImagePickerController가 표시되지 않음

itqueen 2020. 12. 27. 20:34
반응형

iOS 8에서 UIImagePickerController가 표시되지 않음


다른 사람이 UIImagePickerControlleriOS 8에서 문제가 있습니까? 아래 방법은 iPad의 iOS 7에서 완벽하게 작동하지만 선택기를 제시하려고 할 때 XCode 6 (베타 3 또는 4)에서 실행하면 다음 오류가 발생합니다 (마지막 줄). 중요한 경우 sourceType의 선택은 동일한 위치에 표시되는 alertView에서 비롯됩니다.

Warning: Attempt to present <UIImagePickerController: 0x7c0ae400>  on <CAGUCreateContactViewController: 0x7bf61a00> which is already presenting (null)

imagePicker를 여는 방법입니다.

- (void)openPhotoPicker:(UIImagePickerControllerSourceType)sourceType
{
    if ([UIImagePickerController isSourceTypeAvailable:sourceType]) {
        NSArray *availableMediaTypes = [UIImagePickerController availableMediaTypesForSourceType:sourceType];
        if ([availableMediaTypes containsObject:(NSString *)kUTTypeImage]) {
            UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
            imagePickerController.modalPresentationStyle = UIModalPresentationFullScreen;
            imagePickerController.sourceType = sourceType;
            imagePickerController.mediaTypes = @[(NSString *)kUTTypeImage];
            imagePickerController.delegate = self;

            self.imagePickerController = imagePickerController;

            if (sourceType == UIImagePickerControllerSourceTypeCamera) {
                [self presentViewController:self.imagePickerController animated:YES completion:nil];
            } else {                    
                if (self.popoverVC) {
                    [self.popoverVC dismissPopoverAnimated:YES];
                    self.popoverVC = nil;
                }

                self.popoverVC = [[UIPopoverController alloc] initWithContentViewController:imagePickerController];
                [self.popoverVC presentPopoverFromRect:self.nameAndPicCell.picture.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
            }
        }
    }
}

iOS 8에서는 경고보기와 작업 시트가 실제로보기 컨트롤러 ( UIAlertController)로 표시되기 때문이라고 생각합니다 . 따라서의 작업에 대한 응답으로 새 뷰 컨트롤러를 제공하는 경우이 컨트롤러 가 해제되는 UIAlertView동안 표시 UIAlertController됩니다. UIImagePickerController다음과 같이 runloop의 다음 반복까지의 프레젠테이션을 지연하여이 문제를 해결했습니다 .

[[NSOperationQueue mainQueue] addOperationWithBlock:^{
    [self openPhotoPicker:sourceType];
}];

그러나이 문제를 해결하는 적절한 방법은 UIAlertControlleriOS 8 에서 새 API 를 사용하는 것입니다 (예 : if ([UIAlertController class])...를 사용 하여 테스트). 아직 새 API를 사용할 수없는 경우의 해결 방법입니다.


Ben Lings 문제 감지에 동의합니다. UIActionSheet를 사용할 때 더 간단한 솔루션을 제안합니다. Action Sheet 선택에 반응하는 내 코드를 다음에서 이동했습니다.

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex;
{
// my code
}

으로:

- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex;  // after animation
{
// my code
}

이러한 방식으로 앱은 UIActionSheet 애니메이션이 완료된 후 코드가 실행될 것임을 보장합니다.

UIAlertView에는 유사한 델리게이트 메서드가 있기 때문에 :

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex;  // after animation
{
// my code
}

비슷한 해결책이 적용될 수 있다고 생각합니다.


나를 위해 일한 솔루션이 있습니다.

if([[[UIDevice currentDevice] systemVersion] floatValue]>=8.0)
{
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{

        [self presentViewController:cameraUI animated:NO completion:nil];
    }];

}
else{

    [controller presentViewController:cameraUI animated:NO completion:nil];
}

할당하는 것을 잊지 마십시오 cameraUI

UIImagePickerController *cameraUI = [[UIImagePickerController alloc] init];
cameraUI.sourceType = UIImagePickerControllerSourceTypeCamera;

빌드 앤 고!


iOS 8에서 동일한 문제에 직면했습니다. 그런 다음 iOS 즉, 8.0.2에 대한 최신 업데이트의 변경 로그를 장치에서 보았습니다.

이 업데이트에서 언급 된 내용 _

"일부 앱이 사진 보관함의 사진에 접근하지 못하던 문제 수정"

따라서 iOS 8.0.2 버전이 설치된 장치에서 XCode 6을 사용하여 앱을 테스트하십시오. 잘 작동합니다. iOS 8.0 시뮬레이터에서 테스트하지 마십시오.

이것은 나를 도왔고 당신에게도 똑같이 희망합니다.

iOS 8.0.2 업데이트 변경 로그 스크린 샷


UIImagePickerController *imagePickerController= [[UIImagePickerController alloc] init];
[imagePickerController setSourceType:UIImagePickerControllerSourceTypePhotoLibrary];

// image picker needs a delegate so we can respond to its messages
[imagePickerController setDelegate:self];
self.shouldCallViewWillAppear = NO;

if(IS_IOS8)
{
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        // Place image picker on the screen
        [self presentViewController:imagePickerController animated:YES completion:nil];
    }];
}
else
{
    [self presentViewController:imagePickerController animated:YES completion:nil];
}

다음을 사용하여 제시된 뷰 컨트롤러 (있는 경우)를 해제 할 수 있습니다.

[self.presentedViewController dismissViewControllerAnimated:YES completion:nil];

이것은 나를 위해 일했습니다.


해야 할 일은 이미 제시된 ViewController를 닫는 것입니다.

if (self.presentedViewController) {
    [self.presentedViewController dismissViewControllerAnimated:YES completion:nil];
}

[self openPhotoPicker:sourceType];

그래도 오류가 발생하면 openPhotoPicker :를 완료 처리기에 넣습니다.


나는 단순히 이것을했다 :

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,
                                         (unsigned long)NULL), ^(void) {

    [self retractActivePopover];

    dispatch_async(dispatch_get_main_queue(), ^ {

        _activePopover=imagePickerPopover;

        UIBarButtonItem *callingButton = (UIBarButtonItem*) sender;

        [imagePickerPopover presentPopoverFromBarButtonItem:callingButton permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];

    });

});

iOS 8에서는 새 API를 사용해야합니다.

if (SYSTEM_VERSION_IOS_8) {
    self.imagePickerController.modalPresentationStyle = UIModalPresentationPopover;
    UIPopoverPresentationController *popPC = self.imagePickerController.popoverPresentationController;
    popPC.barButtonItem = self.popoverItem;
    popPC.permittedArrowDirections = UIPopoverArrowDirectionAny;
    [self presentViewController:self.imagePickerController animated:YES completion:nil]
}

2014 년 WWDC 세션 228에서 측면 프레젠테이션 컨트롤러 살펴보기를 권장합니다.


iPad와 iPhone 모두에서 작동하는 솔루션을 찾기 위해 많은 고통을 겪었습니다. 이것은 다른 사람들의 의견에서 나온 최종 코드입니다. 코드에는 버그가 있지만 시작하기에 아주 좋은 곳입니다. )

정의 :

__weak IBOutlet UIButton *attachButton;
UIImage *image;

버튼의 동작 :

    - (IBAction)doAttach:(id)sender {
    UIActionSheet *action = [[UIActionSheet alloc] initWithTitle:@"Select image from" delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles:@"From library",@"From camera", nil] ;
    [action showInView:self.view];
  }



#pragma mark - ActionSheet delegates

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if( buttonIndex == 1 ) {
        AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
        if(authStatus == AVAuthorizationStatusAuthorized)
        {
            NSLog(@"%@", @"You have camera access");
        }
        else if(authStatus == AVAuthorizationStatusDenied)
        {
            NSLog(@"%@", @"Denied camera access");

            [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
                if(granted){
                    NSLog(@"Granted access to %@", AVMediaTypeVideo);
                } else {
                    [self.presentedViewController dismissViewControllerAnimated:YES completion:nil];
                    UIAlertController* alert = [UIAlertController alertControllerWithTitle:@“no camera access“
                                                                                   message: @“if you need to use camera in this application go to settings -> appName -> and turn on camera.”
                                                                            preferredStyle:UIAlertControllerStyleAlert];

                    UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@“ok” style:UIAlertActionStyleDefault
                                                                          handler:^(UIAlertAction * action) {
                                                                          }];
                    [alert addAction:defaultAction];

                    [self presentViewController:alert animated:YES completion:nil];


                    NSLog(@"Not granted access to %@", AVMediaTypeVideo);
                    return ;
                }
            }];
        }
        else if(authStatus == AVAuthorizationStatusRestricted)
        {
            [self.presentedViewController dismissViewControllerAnimated:YES completion:nil];
            UIAlertController* alert = [UIAlertController alertControllerWithTitle:@“no camera access“
                                                                                   message: @“if you need to use camera in this application go to settings -> appName -> and turn on camera.”
                                                                            preferredStyle:UIAlertControllerStyleAlert];

            UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@“ok” style:UIAlertActionStyleDefault
                                                                  handler:^(UIAlertAction * action) {
                                                                  }];
            [alert addAction:defaultAction];

            [self presentViewController:alert animated:YES completion:nil];


            NSLog(@"%@", @"Restricted, normally won't happen");
        }
        else if(authStatus == AVAuthorizationStatusNotDetermined)
        {
            NSLog(@"%@", @"Camera access not determined. Ask for permission.");

            [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
                if(granted){
                    NSLog(@"Granted access to %@", AVMediaTypeVideo);
                } else {
                    NSLog(@"Not granted access to %@", AVMediaTypeVideo);
                    return ;
                }
            }];
        }
        else
        {
            [self.presentedViewController dismissViewControllerAnimated:YES completion:nil];
            UIAlertController* alert = [UIAlertController alertControllerWithTitle:@“No camera access“
                                                                           message: @“error accusing camera”
                                                                    preferredStyle:UIAlertControllerStyleAlert];

            UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@“ok” style:UIAlertActionStyleDefault
                                                                  handler:^(UIAlertAction * action) {
                                                                  }];
            [alert addAction:defaultAction];

            [self presentViewController:alert animated:YES completion:nil];


            return;
            //NSLog(@"%@", @"Camera access unknown error.");
        }

        if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {


            UIImagePickerController *pickerView =[[UIImagePickerController alloc]init];
            pickerView.allowsEditing = YES;
            pickerView.delegate = self;
            pickerView.sourceType = UIImagePickerControllerSourceTypeCamera;


            if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {

                [ self.presentedViewController dismissViewControllerAnimated:YES completion:nil ];

                pickerView.modalPresentationStyle = UIModalPresentationPopover;
                UIPopoverPresentationController *popPC = pickerView.popoverPresentationController;
                popPC.sourceView = attachButton;
                popPC.permittedArrowDirections = UIPopoverArrowDirectionAny;
                [self presentViewController:pickerView animated:YES completion:nil];
            } else {
                [self presentModalViewController:pickerView animated:YES ];
            }
        }

    }else if( buttonIndex == 0 ) {

        ALAuthorizationStatus status = [ALAssetsLibrary authorizationStatus];
        switch (status) {
            case ALAuthorizationStatusRestricted:
            case ALAuthorizationStatusDenied:
            {
                [self.presentedViewController dismissViewControllerAnimated:YES completion:nil];
                UIAlertController* alert = [UIAlertController alertControllerWithTitle:@“no access to library”
                                                                               message: @“if you wish to access photos in this app go to settings -> appName-> and turn on photos .”
                                                                        preferredStyle:UIAlertControllerStyleAlert];

                UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@“ok” style:UIAlertActionStyleDefault
                                                                      handler:^(UIAlertAction * action) {
                                                                      }];
                [alert addAction:defaultAction];

                [self presentViewController:alert animated:YES completion:nil];

            }
                break;

            default:
            {
                UIImagePickerController *pickerView = [[UIImagePickerController alloc] init];
                pickerView.allowsEditing = YES;
                pickerView.delegate = self;

                [pickerView setSourceType:UIImagePickerControllerSourceTypePhotoLibrary];


                if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {

                    [ self.presentedViewController dismissViewControllerAnimated:YES completion:nil ];

                    pickerView.modalPresentationStyle = UIModalPresentationPopover;
                    UIPopoverPresentationController *popup = pickerView.popoverPresentationController;
                    popup.sourceView = attachButton;
                    popup.permittedArrowDirections = UIPopoverArrowDirectionAny;
                    [self presentViewController:pickerView animated:YES completion:nil];
                } else {
                    [self presentModalViewController:pickerView animated:YES ];
                }
            }
                break;
        }



    }
}

#pragma mark - PickerDelegates

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{

    [self dismissModalViewControllerAnimated:true];

    UIImage * img = [info valueForKey:UIImagePickerControllerEditedImage];
    image = img;

}

performSelector : withObject : afterDelay가 내 문제를 해결했습니다.

didDismissWithButtonIndex도 트릭을 수행합니다.

최대


다음은 Xamarin 솔루션입니다. 나를 위해 일한 것은 Dismissed 이벤트 핸들러에 내 작업을 추가하는 것이 었습니다.

this.btnPhoto.TouchUpInside += (sender, e) =>
{
    actionSheet = new UIActionSheet ("Add Photo");
    actionSheet.AddButton ("Take Photo");
    actionSheet.AddButton ("Select from Library");
    actionSheet.AddButton ("Cancel");
    actionSheet.DestructiveButtonIndex = -1; // red
    actionSheet.CancelButtonIndex = 3;  // black
    actionSheet.Clicked += delegate(object a, UIButtonEventArgs b)
    {
        actionSheet.Dismissed += (object aSender, UIButtonEventArgs dismissArgs) => 
        {
            switch (dismissArgs.ButtonIndex)
            {
                case 0:
                    showCamera ();
                    break;
                case 1:
                    showPhotoLibrary ();
                    break;
            }
        };
    };
    actionSheet.ShowInView (view);
};

참조 URL : https://stackoverflow.com/questions/24942282/uiimagepickercontroller-not-presenting-in-ios-8

반응형