렌더링되지 않은보기를 iOS 8 스냅 샷하면 빈 스냅 샷이 생성됩니다.


228

iOS 8에서 지금까지 카메라에서 이미지를 캡처하는 데 문제가 있습니다.

UIImagePickerController *controller=[[UIImagePickerController alloc] init];
controller.videoQuality=UIImagePickerControllerQualityTypeMedium;
controller.delegate=(id)self;
controller.sourceType=UIImagePickerControllerSourceTypeCamera;
[self presentViewController:controller animated:YES completion:nil];

그러나 iOS 8에서 나는 이것을 얻고있다 :

Snapshotting a view that has not been rendered results in an empty snapshot. Ensure your view has been rendered at least once before snapshotting or snapshot after screen updates.

나는이 제공하는 솔루션을 시도한 이 게시물

@property (strong,nonatomic)UIImagePickerController *controller;

_controller=[[UIImagePickerController alloc] init];
_controller.videoQuality=UIImagePickerControllerQualityTypeMedium;
_controller.delegate=(id)self;
_controller.sourceType=UIImagePickerControllerSourceTypeCamera;
_[self presentViewController:controller animated:YES completion:nil];

...
controller.modalPresentationStyle=UIModalPresentationFullScreen;
or
controller.modalPresentationStyle=UIModalPresentationCurrentContext;
...

double delayInSeconds = 0.1;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    [self presentViewController:controller animated:YES completion:nil];
});

[self presentViewController:controller animated:YES completion:NULL];

[self presentViewController:controller animated:YES completion:^{

}];

어떤 생각?


3
같은 문제가 있으며 더 많은 버그로 인해 앱이 때때로 충돌합니다. 희망 업데이트 8.0.2가이 버그를 수정합니다. iOS7에서 앱을 실행하면 어리석은 경고없이 매력처럼 작동합니다. iOS 8의 안정성이 먼 것 같습니다.
NCFUSN

9
8.0.2 업데이트로이 문제가 계속 발생합니다
ArdenDev

2
나는 같은 문제를 겪고 있었다. 사진을 찍은 후 다른 스레드에서 처리를하고있었습니다. 코드를 메인 스레드로 옮긴 후 모든 것이 정상이었습니다. 즉, 내 코드는 이전했다 : dispatch_async(dispatch_get_main_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{I로 변경하는dispatch_async(dispatch_get_main_queue(), ^{
mikeyq6

9
iOS 8.1에서 동일한 문제가 발생합니다
랩터

12
iOS 9에서도 발생합니다.
Sebyddd

답변:


131

나는 이것이 iOS 8.0의 버그 일 것이라고 확신합니다. UIImagePickerController위에서 했던 것처럼 프레젠테이션을 시도하는 것 이상을 수행하지 않는 가장 간단한 POC 앱으로 재현 할 수 있습니다. 또한 이미지 선택기 / 카메라를 표시하는 대안 패턴이 없습니다. Apple의 Using UIImagePickerController 샘플 앱을 다운로드 하여 실행하면 동일한 오류가 즉시 발생합니다.

즉, 기능은 여전히 ​​나를 위해 작동합니다. 경고 / 오류 이외의 앱 기능에 문제가 있습니까?


2
아마도 버그 일 것입니다. 코드도 제대로 작동합니다.
souvickcse

4
@souvickcse이 오류가 발생했습니다. 발생할 때마다 새 사진을 촬영 한 후 나타나는 이미지 미리보기는 완전히 검은 색입니다. 그러나 화면 하단의 "다시 촬영"및 "사진 사용"버튼이 여전히 나타나고 제대로 작동합니다. 이 같은 행동을 목격하고 있습니까?
Barry Beerman

3
@souvickcse 나는 여기에있는 최신 phonegap 카메라 플러그인 기준을 사용하고 있습니다 : github.com/apache/cordova-plugin-camera . 모든 아이폰 5에 아이폰 OS 7.1을 실행으로 잘 작동하지만 난 아이폰 6에 아이폰 OS 8을 사용하여 제대로 작동 얻을 수있는 방법을 찾을 수 없습니다
배리 Beerman

2
iOS8.1 final과 동일한 기능
fvisticot

4
IOS 9에도 여전히 존재
목회자

45

몇 시간 동안이 문제로 어려움을 겪고 있었으며 모든 관련 주제를 읽었으며 내 장치의 개인 정보 설정에서 내 앱에 대한 카메라 액세스가 차단되어 오류가 발생했습니다. 나는 카메라에 대한 액세스를 거부 한 적이 없으며 그것이 어떻게 차단되었는지는 모르지만 그것이 문제였습니다!


4
그것이 실제로 당신을 위해 일했는지 확실하지 않지만 그것은 나를 위해 작동하지 않았습니다. @KevinH가 정확하기를 바랍니다.
Deepak Thakur

4
아니요, 필자의 경우 해당 앱의 카메라 액세스가 켜져 있습니다. 그러나 나는 이것이 설정에 의해 간접적으로 야기 될 수 있다고 믿는다 : 설정에 대한 변경은 때때로 즉시 적용되지 않으며, 쿠퍼 티노의 누군가는 어딘가에 동기화하기위한 호출을 최적화해야한다
Anton Tropashko

이 제안으로 문제가 해결되었습니다. 카메라 선택기가 앱에 나타 났을 때 이전에 "허용 안 함"을 터치했습니다. 카메라에 액세스 할 때마다 물어볼 것이라고 생각했지만 그렇지 않았습니다. 설정> 개인 정보 보호> 카메라로 이동하여 앱의 슬라이더를 켜야했습니다. 그런 다음 제대로 작동했습니다. ... 각 시간을 요구하지 애플의 부분에 그렇다고 바보 같은데
존 Contarino

정확히, 때로는 이러한 유형의 실수로 인해 문제가 제기 된 것으로 생각할 수 없습니다. 매우 도움이 들으 친구
Mr.Javed Multani

가장 좋은 옵션은 카메라를 사용하여 기능이 활성화되어 있는지 감지하기 전에 사용하지 않는 경우 설정에서 카메라가 활성화 될 때까지 사진을 찍을 수 없다는 것을 사용자에게 알리는 것입니다. iOS 10에서는 사용자를 특정 앱 설정으로 보낼 수 있습니다 (iOS 8 이전에는 가능했지만 올바르게 호출하면 iOS 8 및 9에서는 불가능).
kindaian

33

위의 @ greg 's answer에 대한 의견이 충분하지 않으므로 여기에 관찰 내용을 추가하십시오. iPad와 iPhone 모두에 대한 Swift 프로젝트가 있습니다. 메인 뷰 컨트롤러 내부에 메소드가 있습니다 (아래 관련 비트). 전화로 테스트하면 모든 것이 올바르게 작동하고 경고가 생성되지 않습니다. iPad에서 실행하면 모든 것이 제대로 작동하지만 뷰 스냅 샷에 대한 경고가 표시됩니다. 그러나 재미있는 점은 팝 오버 컨트롤러를 사용하지 않고 iPad에서 실행할 때 모든 것이 경고없이 올바르게 작동한다는 것입니다. 안타깝게도 Apple은 카메라를 사용하지 않을 경우 이미지 선택기를 iPad의 팝 오버 내에서 사용해야합니다.

    dispatch_async(dispatch_get_main_queue(), {
        let imagePicker: UIImagePickerController = UIImagePickerController();
        imagePicker.sourceType = UIImagePickerControllerSourceType.SavedPhotosAlbum;
        imagePicker.mediaTypes = [kUTTypeImage];
        imagePicker.allowsEditing = false;
        imagePicker.delegate = self;

        if(UIDevice.currentDevice().userInterfaceIdiom == .Pad){ // on a tablet, the image picker is supposed to be in a popover
            let popRect: CGRect = buttonRect;
            let popover: UIPopoverController = UIPopoverController(contentViewController: imagePicker);
            popover.presentPopoverFromRect(popRect, inView: self.view, permittedArrowDirections: UIPopoverArrowDirection.Up, animated: true);
        }else{
            self.presentViewController(imagePicker, animated: true, completion: nil);
        }
    });

iOS 9.0.2에서도 오류 메시지가 표시되므로 올바른 제안 인 것 같습니다. iPhone 전용 앱이 있고 iPad Mini에서 실행할 때 이미지 선택기를 표시 할 때 해당 메시지가 표시됩니다. 어떤 이유로 iOS는 iPad 앱을 실행한다고 생각합니다.
John Tracid

16

콜백에서 UIAlertView 델리게이트로 UIImagePickerController presentViewController :를 호출 한 후이 문제가 발생했습니다. dispatchViewasync를 사용하여 현재 실행 추적을 호출하여 presentViewController를 밀어 문제를 해결했습니다.

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
    dispatch_async(dispatch_get_main_queue(), ^{
        UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
        imagePickerController.delegate = self;

        if (buttonIndex == 1)
            imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
        else
            imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;

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

이것이 나를 위해 해결 한 것입니다. UIAlertAction의 액션 블록 내부에서 UIImagePickerController를 제시하려고했습니다.
josefdlange

alertView가 더 이상 사용되지 않습니다. 대신 UIAlertViewController 작업 내에서 비동기를 사용하면 작동합니까?
DrPatience

@DrPatience는 물론이다. dispatch_async는 원하는 곳에서 작동합니다. 그것이 필요한지 모르겠습니다 (코드에 따라 다름). GCD를 읽으십시오-많은 용도가 있습니다.
greg

12

일부 뷰에 애니메이션을 적용 할 때이 문제가 발생했으며 앱이 백그라운드 모드로 전환되어 다시 돌아옵니다. 플래그를 활성으로 설정하여 처리했습니다. 나는 그것을 NO로 설정했다.

- (void)applicationWillResignActive:(UIApplication *)application

그리고 예

- (void)applicationDidBecomeActive:(UIApplication *)application

내 견해에 따라 애니메이션을 적용하거나 애니메이션을 적용하지 않습니다. 문제를 해결했습니다.


11

UIAlertControllerStyleActionSheet를 사용하여 사용자가 카메라로 사진을 찍거나 라이브러리에서 사진을 사용할 수있는 옵션을 제공했습니다.

오류 메시지에서 상징적 중단 점을 시도했습니다. 여기에 이미지 설명을 입력하십시오

프레젠테이션 중에 UICollectionView를 인턴으로 사용하면 오류가 발생했습니다.

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

여기에 이미지 설명을 입력하십시오

제시하기 전에 프레임을 신속하게 설정 하여이 문제를 해결했습니다.

[alert setPreferredContentSize: alert.view.frame.size];

오류없이 작동하는 완전한 방법은 다음과 같습니다.

-(void)showImageSourceAlertFromSender:(id)sender{
UIButton *senderButton = (UIButton*)sender;
UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *cameraAction = [UIAlertAction actionWithTitle:@"Camera" style:UIAlertActionStyleDefault
                                                     handler:^(UIAlertAction *action) {
                                                         [self takePhoto];
                                                     }];
UIAlertAction *libraryAction = [UIAlertAction actionWithTitle:@"Library" style:UIAlertActionStyleDefault
                                                      handler:^(UIAlertAction *action) {
                                                          [self selectPhotoFromLibraryFromSender:sender];
                                                      }];
[alert addAction:cameraAction];
[alert addAction:libraryAction];
alert.popoverPresentationController.delegate = self;
alert.popoverPresentationController.sourceRect = senderButton.frame;
alert.popoverPresentationController.sourceView = self.view;

[alert setPreferredContentSize: alert.view.frame.size];

[self presentViewController:alert animated:YES completion:^(){
}];}

10

view뷰 컨트롤러를 제시하기 전에 속성 을 참조하여 "뷰 스냅 샷"경고 를 끄십시오. 그렇게하면 뷰가로드되고 iOS가이를 렌더링하여 스냅 샷을 생성 할 수 있습니다.

UIAlertController *controller = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
controller.modalPresentationStyle = UIModalPresentationPopover;
controller.popoverPresentationController.barButtonItem = (UIBarButtonItem *)sender;

... setup the UIAlertController ... 

[controller view]; // <--- Add to silence the warning.

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

거의 유용한 팁입니다. 감사합니다!!!! (내 경우에는 여전히 경고 메시지가 표시되지만 앱이 더 이상 충돌하지 않습니다.)
Fattie

cameraOverlayView그러나을 추가 해도 불행히도이 팁을 적용해도 여전히이 문제가 발생합니다.
Fattie

8

이미지 캡처 후 검은 색 미리보기에 문제가있는 사람은 UIPickerController가 표시된 후 상태 표시 줄을 숨기면 문제가 해결 된 것으로 보입니다.

UIImagePickerControllerSourceType source = [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera] ? UIImagePickerControllerSourceTypeCamera : UIImagePickerControllerSourceTypeSavedPhotosAlbum;
UIImagePickerController *cameraController = [[UIImagePickerController alloc] init];
        cameraController.delegate = self;
        cameraController.sourceType = source;
        cameraController.allowsEditing = YES;
        [self presentViewController:cameraController animated:YES completion:^{
            //iOS 8 bug.  the status bar will sometimes not be hidden after the camera is displayed, which causes the preview after an image is captured to be black
            if (source == UIImagePickerControllerSourceTypeCamera) {
                [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
            }
        }];

1
나는 위의 방법을 시도했지만 아무도 효과가 없었습니다. 그리고 이것은 효과가있었습니다
Stan

솔루션이 작동하지 않습니다. 그 시점에서 이미지를 캡처 할 때 StatusBar가 이미 숨겨져 있다고 생각합니다.
Mihir Oza 2016 년

5

나는 같은 문제를 발견하고 모든 것을 시도했다. objective-C에 하나와 swift에 하나의 두 가지 다른 앱이 있습니다. 둘 다 같은 문제가 있습니다. 오류 메시지가 디버거에 나타나고 첫 번째 사진 다음에 화면이 검게 변합니다. 이것은 iOS> = 8.0에서만 발생합니다. 분명히 버그입니다.

어려운 해결 방법을 찾았습니다. imagePicker.showsCameraControls = false로 카메라 컨트롤을 끄고 누락 된 버튼이있는 고유 한 overlayView를 만듭니다. 이 작업을 수행하는 방법에 대한 다양한 자습서가 있습니다. 이상한 오류 메시지는 유지되지만 최소한 화면이 어두워지지 않고 작동하는 앱이 있습니다.


나는 당신과 똑같은 문제를 겪었습니다. 아래 내 대답을 참조하십시오.
Dan

5

내장 ImagePickerController의 버그 일 수 있습니다. 내 코드가 작동하지만 iPhone 6 Plus에서 때때로 충돌합니다.

다른 답변에서 제안한 모든 솔루션을 시도했지만 운이 없었습니다. JPSImagePickerController로 전환 한 후 문제가 마침내 해결되었습니다 .


3

나는 모든 것을 시도했지만 내 문제는 카메라와 사진 라이브러리의 이미지 선택기가 표시 된 직후 사라 졌다는 것입니다. 나는 다음 줄로 해결했다 (신속한)

imagePicker.modalPresentationStyle = UIModalPresentationStyle.OverCurrentContext

3

나는 이것이 iOS 8.0의 버그 일 것이라고 확신합니다. 위와 같이 UIImagePickerController를 제시하는 것 이상을 수행하지 않는 가장 간단한 POC 앱으로 재현 할 수 있습니다. 또한 이미지 선택기 / 카메라를 표시하는 대안 패턴이 없습니다. Apple의 Using UIImagePickerController 샘플 앱을 다운로드하여 실행하면 동일한 오류가 즉시 발생합니다.

즉, 기능은 여전히 ​​나를 위해 작동합니다. 경고 / 오류 외에 앱 기능에 문제가 있습니까?


3

UIImagePickerController속성을 속성으로 사용하면 이 경고가 사라집니다.within 함수를 UIImagePickerController인스턴스화하는 경우 의 결과를 사용하지 않는 것으로 가정합니다 UIImagePickerController.


2

이 방법을 호출하면 나에게 도움이되었습니다. 보기를 제시 한 후 배치하십시오.

[yourViewBeingPresented.view layoutIfNeeded];

1

또한 동일한 문제가 발생하여 카메라를 사용할 수 있는지 확인하여 문제를 해결했습니다.

BOOL cameraAvailableFlag = [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera];
    if (cameraAvailableFlag)
        [self performSelector:@selector(showcamera) withObject:nil afterDelay:0.3];

1
isSourceTypeAvailable은 내 앱의 카메라에 대한 액세스를 거부했지만 true를 반환합니다. 카메라 액세스가 거부되면 디스플레이에 아무 것도 표시되지 않습니다.
Καrτhικ

1

나는이 문제를 만났다. 카메라를 호출하고 뷰를 해제하면이 문제가 발생합니다. 예를 들어 viewDidDisappear 메소드에서 카메라를 호출하고 view nil을 설정하면 카메라 이벤트에 대한 콜백이 없기 때문에이 오류가 발생합니다. 이 오류에 대해서도이 사례를 확인하십시오.


1

카메라를 여는 동안 콘솔에 다음과 같은 메시지가 표시됩니다.

'렌더링되지 않은 뷰를 스냅 샷하면 빈 스냅 샷이 생성됩니다. 화면을 업데이트 한 후 스냅 샷 또는 스냅 샷을하기 전에 뷰가 한 번 이상 렌더링되었는지 확인하십시오. '

나에게 문제는 Info.plist 파일의 번들 표시 이름과 관련이 있습니다. 어떻게 비어있었습니다. 내 앱 이름을 입력하면 정상적으로 작동합니다. 빈 번들 표시 이름 때문에 카메라 권한 경고를받지 못했습니다. 뷰 렌더링을 차단했습니다.

문제가 보이지 않았지만 권한없이 제시하면 설정-> 개인 정보-> 카메라에서 확인할 수 있습니다. 앱이 목록에 없으면 문제가 동일 할 수 있습니다.


1

Phonegap을 사용하고 있지만이 스레드는 오류 메시지에 대해 인터넷 검색을 할 때 첫 번째 스레드로 계속 나타납니다.

나 에게이 문제는 이미지 유형을 PNG로 정의하여 사라졌습니다.

encodingType : Camera.EncodingType.PNG

따라서 전체 라인은 다음과 같습니다.

 navigator.camera.getPicture(successFunction, failFunction, { encodingType : Camera.EncodingType.PNG, correctOrientation:true, sourceType : Camera.PictureSourceType    .PHOTOLIBRARY, quality: 70, allowEdit : false , destinationType: Camera.DestinationType.DATA_URL});

귀하의 마일리지는 다를 수 있지만 그것은 나를 위해 속였습니다.


1

또는 다음을 사용하십시오 drawViewHierarchyInRect.

빠른:

extension UIImage{

    class func renderUIViewToImage(viewToBeRendered: UIView) -> UIImage
    {
        UIGraphicsBeginImageContextWithOptions(viewToBeRendered.bounds.size, true, 0.0)
        viewToBeRendered.drawViewHierarchyInRect(viewToBeRendered.bounds, afterScreenUpdates: true)
        viewToBeRendered.layer.renderInContext(UIGraphicsGetCurrentContext()!)

        let finalImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return finalImage
    }
}

목표 -C :

- (UIImage *)snapshot:(UIView *)view
{
    UIGraphicsBeginImageContextWithOptions(view.bounds.size, YES, 0);
    [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:YES];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}

참조 :


0

제 경우 (XCode 7 및 iOS 9)에서 UINavigationController"숨김"을 사용 하므로 UINavigationControllerDelegate현재 카메라 또는 롤 에 추가 해야하며 예상대로 작동합니다! And pickerControllerDelegate.self오류도 표시하지 않습니다!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.