Ошибка UIImagePickerController: создание снимка представления, которое не было обработано, приводит к созданию пустого снимка в iOS 7

103

Я получаю эту ошибку только в iOS 7, и приложение вылетело. В iOS 6 я никогда не получаю никаких ошибок, только одно предупреждение о памяти при открытии камеры.

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.

Вот что я делаю.

imagePicker = [[UIImagePickerController alloc] init];
[imagePicker setDelegate:self];
[imagePicker setSourceType:UIImagePickerControllerSourceTypeCamera];
[imagePicker setAllowsEditing:YES];

[self presentModalViewController:imagePicker animated:YES];

Я пытался отложить presentModalViewController, но все равно получаю то же сообщение. Через несколько секунд (7-10) приложение вылетело.

Эта ошибка присутствует только в iOS 7.

Кто-нибудь знает?

Дидац Триади
источник
3
У меня та же проблема. На iOS7 UIIMagePickerController больше не работает.
condor304
Вызов этого метода сработал для меня. Разместите его после представления вашего взгляда. [yourViewBeingPresent.view layoutIfNeeded];
Бобби

Ответы:

32

Проблема в iOS7 связана с переходами. Кажется, что если предыдущий переход не был завершен и вы запускаете новый, iOS7 портит представления, а iOS6, похоже, управляет им правильно.

Вы должны инициализировать свою камеру в вашем UIViewControllerтолько после того, как представление будет загружено и с таймаутом:

- (void)viewDidAppear:(BOOL)animated 
{
    [super viewDidAppear:animated];
    //show camera...
    if (!hasLoadedCamera)
        [self performSelector:@selector(showcamera) withObject:nil afterDelay:0.3];
}

и вот код инициализации

- (void)showcamera {
    imagePicker = [[UIImagePickerController alloc] init];
    [imagePicker setDelegate:self];
    [imagePicker setSourceType:UIImagePickerControllerSourceTypeCamera];
    [imagePicker setAllowsEditing:YES];

    [self presentModalViewController:imagePicker animated:YES];
}
Лефтерис
источник
1
Кажется, пока это работает, я протестировал это, сделав 10 снимков один за другим без проблем.
DevC
3
PresentModalViewController устарел в iOS 6. Предлагается использовать PresentViewController сейчас.
Gallymon
5
Та же проблема и исправление для iOS8.
Евгений Шаученко
1
Я пытаюсь выполнить эту работу из UIAertControl - один вариант - представить средство выбора изображений для браузера фотографий - это работает нормально, а другой - представить для камеры - этого нет. Где бы я мог встроить задержку при использовании UIALertController?
SimonTheDiver
3
Я не инициализирую камеру в viewDidAppear / Load. У меня есть tableview, и я поднимаю камеру в ответ на один из вариантов tableview. И я получаю это сообщение об ошибке. Любые идеи?
Хеннинг
18

Эта ошибка также обнаружилась у меня в проекте примера кода Apple PhotoPicker.

Я использовал Xcode версии 5.0 и iOS 7.0.3 на iPhone 4.

Действия по воспроизведению:

  1. Загрузите образец проекта Apple PhotoPicker по адресу https://developer.apple.com/library/ios/samplecode/PhotoPicker/Introduction/Intro.html.

  2. В APLViewController.m закомментируйте строку 125

    //imagePickerController.showsCameraControls = NO;

  3. В APLViewController.m закомментируйте строки 130-133

    //[[NSBundle mainBundle] loadNibNamed:@"OverlayView" owner:self options:nil];
    // self.overlayView.frame = imagePickerController.cameraOverlayView.frame;
    // imagePickerController.cameraOverlayView = self.overlayView;
    // self.overlayView = nil;

  4. Соберите и запустите приложение.

  5. После запуска поверните устройство в альбомный режим.

  6. Щелкните значок камеры, чтобы открыть UIImagePickerController в режиме камеры.

  7. Просмотрите вывод консоли.

Консольный вывод

PhotoPicker [240: 60b] При создании снимка вида, который не был визуализирован, создается пустой снимок. Убедитесь, что ваше представление было визуализировано хотя бы один раз перед созданием моментального снимка или моментальным снимком после обновления экрана.

showCameraControls свойство

У меня проблема возникает, когда он имеет значение ДА (по умолчанию).

Установка этого параметра в NO устраняет сообщение.

Отчет об ошибке

Я только что отправил отчет об ошибке в Apple.

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

Скотт Картер
источник
1
Как Apple ответила вам? У меня такая же проблема, и решения в stackoverflow не работают.
heekyu 01
Я еще не слышал об этом от Apple. Я отправлю ответ, если получу от них ответ.
Скотт Картер
Есть новости от Apple? @ScottCarter
Бенджамин Туег
1
Только что проверил еще раз. Никаких действий в отношении открытой ошибки не было, поскольку она была зарегистрирована 2 ноября 2013 г.
Скотт Картер,
Это ошибка 15377241 на bugreport.apple.com
Скотт Картер
11

У меня возникла проблема, когда я попытался представить вид камеры внутри всплывающего окна. Под iOS6 это не было проблемой, но в iOS7 я получил сообщение

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.

также.

Однако после того, как я изменил представление камеры на полноэкранный режим, как описано в разделе « Съемка фотографий и фильмов, библиотека разработчика iOS», все снова пошло нормально, и сообщение больше не появлялось. Однако я должен был убедиться, что в зависимости от того, в каком режиме находится приложение (например, отображается вид с камеры или фотопленка), мне нужно было либо закрыть всплывающее окно, либо контроллер представления при каждом - (void) imagePickerControllerDidCancel: (UIImagePickerController *) pickerвызове метода .

Арне
источник
3
cameraUI.modalPresentationStyle = UIModalPresentationFullScreen; работает для меня. Это единственное, что здесь удалось. Спасибо!
daveMac
2
В заключение! У меня была эта проблема много раз, но я так и не нашел хорошего решения. Почувствуйте себя настолько глупо, что никогда не заглядываете дальше в цепочку вопросов - imagePicker.modalPresentationStyle = UIModalPresentationFullScreen; решил это для меня. Это должен быть принятый ответ :)
woobione
6

создать недвижимость

@property (nonatomic) UIImagePickerController *imagePickerController;

затем

UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.modalPresentationStyle = UIModalPresentationCurrentContext;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
picker.allowsEditing = YES;
self.imagePickerController = picker;
[self presentViewController:self.imagePickerController animated:YES completion:nil];

Это должно решить проблему

Асфанур
источник
3
picker.modalPresentationStyle = UIModalPresentationCurrentContext; имел значение для меня.
Мистер Берна
1
Он работает при первом представлении средства выбора, но после этого возвращается предупреждение.
daveMac
я подтверждаю picker.modalPresentationStyle = UIModalPresentationCurrentContext; Решает для меня проблему неправильных макетов в iOS 8
Жуан Нуньес,
Не работает для меня - добавил это в действие UIButton на iOS 8.1.3
Энди
Это казалось многообещающим, но ничего не сделало для меня с проблемой моментального снимка И отобразило бесполезную рамку вокруг части изображения после того, как была сделана фотография.
нарисовал ..
4

Я использовал этот код для решения проблемы:

UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
[imagePicker setSourceType:UIImagePickerControllerSourceTypeCamera];
[imagePicker setDelegate:self];

if ([self respondsToSelector:@selector(presentViewController:animated:completion:)]){
    [imagePicker setShowsCameraControls:NO];
    [self presentViewController:imagePicker animated:YES completion:^{
        [imagePicker setShowsCameraControls:YES];
    }];
} else {
    [imagePicker setShowsCameraControls:YES];
    [self presentModalViewController:imagePicker animated:YES];
}
Germán Marquès
источник
1
Хотя эта идея работает теоретически, к сожалению, показанные элементы управления не работают или отображаются неправильно.
daveMac
И это не избавило от предупреждения (по крайней мере, для меня)
Эге Акпинар
3

У меня такая же проблема, и я нашел решение. Думаю, эта ошибка связана с ориентацией вашего приложения. Мое приложение использует только альбомный режим, но UIImagePickerController использует портретный режим. Я добавляю блок try-catch в main.m и получаю настоящее исключение:

Supported orientations has no common orientation with the application, and shouldAutorotate is returning YES

Как я решаю эту проблему:

1) Еще раз проверьте ориентацию устройства в Target-> General или в файле .plist: Поддерживаемые ориентации интерфейса: альбомная слева, альбомная справа.

2) Добавьте в AppDelegate.m:

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
    return UIInterfaceOrientationMaskLandscape | UIInterfaceOrientationMaskPortrait;
}

После этого шага UIImagePickerController работает правильно, но мои контроллеры представления можно повернуть в портретный режим. Итак, чтобы решить это:

3) Создайте категорию для UINavigationController (поддерживаемыеInterfaceOrientations перемещены из UIViewController в UINavigationController в iOS6):

@implementation UINavigationController (RotationIOS6)

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscape;
}

@end

Это решение корректно работает на iOS 6.0, 6.1, 7.0. Надеюсь это поможет.

Роман Ермолов
источник
1
Я исправляю приложение в портретном режиме, которое выдает ошибку, указанную в OP. Казалось бы, ваше решение не универсально.
JohnK
Вы пытались добавить блок try-catch в main.m и распечатать исключение и трассировку стека?
Роман Ермолов
Как это ?
JohnK
@JohnK да, вот так.
Роман Ермолов
3

Я получаю эту ошибку при создании приложения с помощью iOS SDK 6.1, целевого развертывания iOS 6.1 и запуска приложения на iPhone под управлением iOS 7. Приложение не вылетает, но реализация UIViewController shouldAutorotateметода помогает мне удалить сообщение об ошибке.

- (BOOL)shouldAutorotate {
    return YES;
}
Григорий А.
источник
3

У меня была такая же проблема, когда я пытался изменить демонстрационное приложение, которое поставляется с Avirary SDK , в демонстрационном приложении оно может редактировать только фотографию, выбранную из камеры. Чтобы попытаться отредактировать фотографию путем захвата с камеры, я сначала добавил следующий код в файл UIViewcontroller.m:

#pragma mark - Take Picture from Camera
- (void)showCamera
{
//[self launchPhotoEditorWithImage:sampleImage highResolutionImage:nil];

    if ([self hasValidAPIKey]) {
        UIImagePickerController * imagePicker = [UIImagePickerController new];
        [imagePicker setSourceType:UIImagePickerControllerSourceTypeCamera];
        [imagePicker setDelegate:self];
        [imagePicker setAllowsEditing:YES]; //important, must have

        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
            [self presentViewController:imagePicker animated:YES completion:nil];
        }else{
            [self presentViewControllerInPopover:imagePicker];
        }
    }
}

Затем, когда я запустил приложение, произошла ошибка:

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.

Чтобы устранить ошибку, измените делегат UIImagePicker в файле UIViewContooler.m, как показано ниже:

#pragma mark - UIImagePicker Delegate

- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    NSURL * assetURL = [info objectForKey:UIImagePickerControllerReferenceURL];

    void(^completion)(void)  = ^(void){

        [[self assetLibrary] assetForURL:assetURL resultBlock:^(ALAsset *asset) {
            if (asset){
                [self launchEditorWithAsset:asset];
            }
        } failureBlock:^(NSError *error) {
            [[[UIAlertView alloc] initWithTitle:@"Error" message:@"Please enable access to your device's photos." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
        }];

        UIImage * editedImage = [info objectForKey:UIImagePickerControllerEditedImage];
        if(editedImage){
            [self launchPhotoEditorWithImage:editedImage highResolutionImage:editedImage];
        }

    };

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
        [self dismissViewControllerAnimated:YES completion:completion];
    }else{
        [self dismissPopoverWithCompletion:completion];
    }

}    

Потом ошибка исчезла и приложение работает!

Тони
источник
1

Попробуйте это, используйте

[self performSelector:@selector(presentCameraView) withObject:nil afterDelay:1.0f];

и функция

-(void)presentCameraView{
    [self presentViewController:imagePicker animated:YES completion:nil];
}

заменить. [self presentModalViewController:imagePicker animated:YES]; и, конечно же, make imagePickerкак глобальная переменная.

ДжерриЧжоу
источник
1

Вот что исправило это для меня в моем приложении, ymmv

во-первых, это iPhone - приложение для iPad

в appname-Info.plist. в Поддерживаемых ориентациях интерфейса (iPad) показал 4 ориентации.

в Поддерживаемых ориентациях интерфейса показаны 3 ориентации. Я добавил четвертый и запустил приложение, без отладки.

Надеюсь это поможет.

user1045302
источник
0

Я только что столкнулся с той же проблемой. В моем случае проблема заключалась в том, что у меня был код, не относящийся к ARC, и я перенес его на ARC. Когда я выполнял миграцию, у меня не было сильных ссылок на, UIImagePickerControllerи это было причиной сбоя.

Надеюсь, поможет :)

артургригор
источник
0

У меня была такая же проблема в iOS 8, но доступ к камере был отключен в настройках -> Конфиденциальность для моего приложения. Просто включил его, и он заработал.

БхушанВУ
источник
0

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

Вот что вы сделаете, чтобы получить выбранное изображение и продолжить работу :)

-(void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info
{
    UIImage* pickedImage = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
    [composeImageView setImage:pickedImage];
[picker dismissViewControllerAnimated:YES completion:nil];
 }

Да, чтобы решить эту проблему, вам нужно просто закрыть средство выбора в обычном режиме, поскольку кажется, что это сообщение: «Снимок вида, который не был визуализирован, приводит к пустому снимку. Убедитесь, что ваше представление было визуализировано хотя бы один раз перед созданием снимка или снимком после обновления экрана ". останавливает отклик средства выбора, но вы можете закрыть его и получить изображение в обычном режиме.

ДевШериф
источник
0

В моем случае это было связано с изменением макета: VC, представляющий, UIImagePickerViewControllerимеет скрытую строку состояния, но UIImagePickerViewControllerне имеет.

Итак, я решил, что он скрывает строку состояния, UIImagePickerViewControllerкак показано в этом ответе .

Канобиус
источник
-1

Не отвечая напрямую на ваш вопрос, но вы упомянули, что у вас есть предупреждение о памяти, вы можете хранить необработанное изображение в свойстве, что может привести к предупреждению о памяти. Это связано с тем, что необработанное изображение занимает примерно 30 МБ памяти. Я заметил подобное предупреждение памяти при тестировании приложений на iOS6, которые были на iPhone 4 серии. Я все еще получал это предупреждение, когда устройства были обновлены до iOS7. При тестировании на iPhone 5 серии на iOS7 предупреждение о памяти не отображается.

DevC
источник
-5

Изменение

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

к

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

исправил проблему для меня.

Юки
источник