Снимок экрана 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:^{

}];

любая идея?

souvickcse
источник
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), ^{То есть, мой код раньше был: который я изменилdispatch_async(dispatch_get_main_queue(), ^{
mikeyq6
9
Та же проблема возникает в iOS 8.1
Raptor
12
Бывает и в iOS 9.
Себидд

Ответы:

131

Я уверен, что это просто ошибка в iOS 8.0. Это воспроизводимо с простейшими приложениями POC, которые делают только попытку представить то, UIImagePickerControllerчто вы делаете выше. Кроме того, насколько мне известно, нет альтернативы шаблону для выбора изображения / камеры. Вы даже можете загрузить пример приложения Apple с использованием UIImagePickerController , запустить его, и он выдаст ту же ошибку из коробки.

Тем не менее, функциональность по-прежнему работает для меня. Помимо предупреждения / ошибки, у вас есть проблемы с функционированием вашего приложения?

KevinH
источник
2
Да, возможно, это ошибка, у меня тоже хорошо работает код.
souvickcse
4
@souvickcse Я тоже сталкиваюсь с этой ошибкой. Всякий раз, когда это происходит, предварительный просмотр изображения, который появляется после того, как был сделан новый снимок, полностью черный. Тем не менее, кнопки «Re-Take» и «Use Photo» в нижней части экрана по-прежнему отображаются и работают правильно. Вы наблюдаете такое же поведение?
Барри Берерман,
3
@souvickcse Я использую самую последнюю версию плагина для телефонной камеры, расположенную здесь: github.com/apache/cordova-plugin-camera . Все отлично работает с iOS 7.1 на iPhone 5, но я не могу найти способ заставить его работать должным образом с помощью iOS 8 на iPhone 6.
Барри Берман,
2
То же самое для меня с финалом iOS8.1
fvisticot
4
Все еще присутствует в IOS 9
Преподобный
45

Я боролся с этой проблемой в течение нескольких часов, я прочитал все соответствующие темы и обнаружил, что ошибка была вызвана тем, что в настройках конфиденциальности моего устройства доступ камеры к моему приложению был заблокирован !!! Я никогда не отказывал в доступе к камере, и я не знаю, как она была заблокирована, но это была проблема!

Пантелис Проиос
источник
4
Я не уверен, действительно ли это сработало для вас, но у меня не сработало. Я просто надеюсь, что @KevinH правильно.
Дипак Тхакур
4
Нет, доступ к камере включен для этого приложения в моем случае. Но я верю, что это может быть вызвано, хотя и косвенно, настройками: изменения в настройках иногда вступают в силу не сразу, кто-то в Купертино, должно быть, оптимизировал вызов для синхронизации где-то
Антон Тропашко
Это предложение решило проблему для меня. Ранее я коснулся «Не разрешать», когда в моем приложении появился селектор камеры. Я думал, что будет спрашивать меня каждый раз, когда я получал доступ к камере, но это не так. Мне пришлось перейти в Настройки> Конфиденциальность> Камера и включить слайдер для моего приложения. Тогда это работало правильно. Кажется глупым со стороны Apple не просить каждый раз ...
Джон Контарино
Точно, иногда мы не можем думать о проблеме, поднятой для этого типа ошибок. спасибо приятель
Mr.Javed Multani
Лучше всего перед использованием камеры определить, активна ли эта функция, и, если нет, предупредить пользователя о том, что фотографирование недоступно, пока камера не активирована в настройках. На iOS 10 возможно отправить пользователя с определенными настройками приложения (было возможно до iOS 8, но невозможно в iOS 8 и 9, если я правильно помню).
любезно
33

У меня недостаточно очков репутации, чтобы комментировать ответ @ greg выше, поэтому добавлю свои наблюдения здесь. У меня есть проект Swift для iPad и iPhone. У меня есть метод внутри моего основного контроллера вида (соответствующий бит ниже). Когда я проверяю это на телефоне, все работает правильно, и никаких предупреждений не генерируется. Когда я запускаю его на iPad, все работает правильно, но я вижу предупреждение о снимке экрана. Интересным моментом, однако, является то, что когда я работаю на iPad без использования контроллера popover, все работает правильно, без предупреждения. К сожалению, 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);
        }
    });
DLW
источник
Похоже, это правильное предложение, потому что у меня появляется это сообщение об ошибке даже в iOS 9.0.2. У меня есть приложение только для iPhone, и когда я запускаю его на своем iPad Mini, я вижу это сообщение при представлении средства выбора изображений. По какой-то причине iOS считает, что я запускаю приложение для iPad.
Джон Трасид
16

Я столкнулся с этим после вызова UIImagePickerController presentViewController: от обратного вызова до делегата UIAlertView. Я решил эту проблему, нажав presentViewController: отменить текущую трассировку выполнения с помощью dispatch_async.

- (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];
    });
}
Greg
источник
Это то, что решило это для меня. Я пытался представить UIImagePickerController из блока действий UIAlertAction.
Josefdlange
alertView устарел, будет ли это работать, если я вместо этого использую асинхронную операцию внутри действия UIAlertViewController?
DrPatience
@DrPatience Конечно. dispatch_async работает где угодно. Я не знаю, что это необходимо (зависит от вашего кода). Читайте о GCD - он имеет множество применений.
Грег
12

У меня была эта проблема при анимации некоторых видов, и приложение переходило в фоновый режим и возвращалось. Я справился с этим, установив флаг isActive. Я установил это в НЕТ в

- (void)applicationWillResignActive:(UIApplication *)application

и ДА в

- (void)applicationDidBecomeActive:(UIApplication *)application

и оживлять или не оживлять мои взгляды соответственно. Позаботился о проблеме.

byedissident
источник
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:^(){
}];}
Yedy
источник
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];
Стив Шепард
источник
Это почти невероятно полезный совет. Спасибо!!!! (В моем случае я все еще получаю предупреждение, но приложение больше не вылетает.)
Толстяк
Однако, когда я добавляю cameraOverlayView, к сожалению, я все еще получаю эту проблему, даже когда я применяю этот совет.
Толстяк
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
полностью спас мой день! Я пробовал методы выше, ни один не работал. И это сработало
Стэн
Решение не работает. Я думаю, что когда мы делаем снимок, в это время StatusBar уже скрыт.
Михир Оза
5

Я нашел ту же проблему и попробовал все. У меня есть два разных приложения, одно в Objective-C и одно в быстром - оба имеют одинаковую проблему. Сообщение об ошибке появляется в отладчике, и экран становится черным после первой фотографии. Это происходит только в iOS> = 8.0, очевидно, это ошибка.

Я нашел трудный обходной путь. Отключите элементы управления камерой с помощью imagePicker.showsCameraControls = false и создайте собственный вид наложения, в котором отсутствуют кнопки. Существуют различные учебные пособия о том, как это сделать. Странное сообщение об ошибке остается, но по крайней мере экран не гаснет, и у вас есть работающее приложение.

Томас Зиммер
источник
У меня была та же проблема, что и у вас, смотрите мой ответ ниже.
Дан
5

Это может быть ошибка встроенного ImagePickerController. Мой код работает, но иногда вылетает на iPhone 6 Plus.

Я перепробовал все решения, предложенные другими ответами, но безуспешно. Проблема окончательно решена после перехода на JPSImagePickerController .

JonSlowCN
источник
3

Я перепробовал все, моя проблема заключалась в том, что средство выбора изображений для камеры и библиотеки фотографий исчезло сразу после их показа. Я решил это следующей строкой (swift)

imagePicker.modalPresentationStyle = UIModalPresentationStyle.OverCurrentContext
Waffeln
источник
3

Я уверен, что это просто ошибка в iOS 8.0. Его можно воспроизвести с помощью самых простых приложений POC, которые не делают ничего, кроме попытки представить UIImagePickerController, как вы делали выше. Кроме того, насколько мне известно, нет альтернативы шаблону для выбора изображения / камеры. Вы даже можете загрузить пример приложения Apple с использованием UIImagePickerController, запустить его, и он выдаст ту же ошибку из коробки.

Тем не менее, функциональность по-прежнему работает для меня. Помимо предупреждения / ошибки, у вас есть проблемы с функционированием вашего приложения?

Гаурав Патель
источник
3

Если мы используем UIImagePickerController свойство as, то это предупреждение исчезнет.Предположим, что мы не используем результат из 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

Я сталкивался с этой проблемой. Когда мы вызываем камеру и отпускаем взгляды, возникает эта проблема. Для примера, вызов камеры и установка view nil в методе viewDidDisappear эта ошибка произойдет, так как нет обратного вызова для события камеры. Убедитесь в этом случае тоже для этой ошибки.

Гоби М
источник
1

Я получил ту же ошибку, получив сообщение ниже в консоли при открытии камеры.

'Снимок представления, который не был обработан, приводит к пустому снимку. Убедитесь, что ваш вид был обработан хотя бы один раз перед снимком или снимком экрана после обновления экрана. '

Для меня проблема была с отображаемым именем Bundle в Info.plist file.it был каким-то образом пустым, я поместил туда имя моего приложения, и теперь оно работает нормально. Я не получил никакого предупреждения о разрешении камеры из-за пустого отображаемого имени Bundle.it заблокировал вид от рендеринга.

проблема была не в просмотре, а в представлении без разрешения. Вы можете проверить это в настройках -> конфиденциальность -> Камера, если ваше приложение не указано в списке, проблема может быть такой же.

Шабер Али
источник
1

Я использую Phonegap, но эта тема продолжает появляться первой, когда Google указывает на сообщение об ошибке.

Для меня эта проблема ушла, определив тип изображения в 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});

Ваш пробег может варьироваться, но это помогло мне.

Jannunen
источник
1

В качестве альтернативы рассмотрите возможность использования drawViewHierarchyInRect:

Swift:

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

Objective-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ошибка тоже не отображается!

Даниэль Арантес Ловерде
источник