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), ^{який я змінивdispatch_async(dispatch_get_main_queue(), ^{
mikeyq6

9
Така ж проблема трапляється в iOS 8.1
Raptor

12
Трапляється і в iOS 9.
Sebyddd

Відповіді:


131

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

Однак, функціонал все ще працює для мене. Окрім попередження / помилки, у вас є проблеми з функціонуванням вашої програми?


2
Так, напевно, це помилка, код працює чудово і для мене.
souvickcse

4
@souvickcse Я також зіткнувся з цією помилкою. Щоразу, коли це відбувається, попередній перегляд зображення, що з’являється після того, як зроблено нове зображення, стає повністю чорним. Однак кнопки «Знову взяти» та «Використовувати фото» внизу екрана все ще з’являються та функціонують належним чином. Ви є свідком такої самої поведінки?
Barry Beerman

3
@souvickcse Я використовую останню базову лінію плагіну для камери phonegap, розміщену тут: github.com/apache/cordova-plugin-camera . Все працює добре з iOS 7.1, що працює на iPhone 5, але я не можу знайти спосіб його роботи належним чином за допомогою iOS 8 на iPhone 6.
Barry Beerman,

2
Те саме для мене з фіналом iOS8.1
fvisticot

4
Все ще присутній в IOS 9
преподобний

45

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


4
Я не впевнений, чи справді він працював для вас, але це не спрацювало для мене. Я просто сподіваюся, що @KevinH вірно.
Діпак Тхакур

4
Ні, доступ до камери встановлено для цього додатка УВІМКНЕНО. Але я вважаю, що це може бути спричинене хоч і опосередковано налаштуваннями: зміни в налаштуваннях не вступають в дію негайно, хтось із купертіно, мабуть, оптимізував дзвінок, щоб десь синхронізуватися
Антон Тропашко

Ця пропозиція вирішила проблему для мене. Раніше я торкнувся "Не дозволяти", коли в моєму додатку з'явився селектор камер. Я думав, що це запитуватиме мене щоразу, коли я отримую доступ до камери, але цього не сталося. Мені довелося зайти в Налаштування> Конфіденційність> Камера та увімкнути повзунок для мого додатка. Тоді це справно спрацювало. Здається, це щось дурне з боку Apple, щоб не просити кожного разу ...
Джон Контаріно

точно, іноді ми не можемо думати, що питання, порушене для цього типу помилок. THX приятель дуже корисний
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);
        }
    });

Схоже, це правильна пропозиція, оскільки я отримую повідомлення про помилку навіть у iOS 9.0.2. У мене є додаток лише для iPhone, і коли я запускаю його на своєму iPad Mini, я бачу це повідомлення під час подання програми вибору зображень. Чомусь iOS вважає, що я запускаю додаток iPad.
Джон Тракід

16

Я наткнувся на це після виклику UIImagePickerController presentViewController: від зворотного дзвінка до делегата UIAlertView. Я вирішив проблему, натиснувши присутнімViewController: відключіть поточний слід виконання за допомогою 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];
    });
}

Це те, що вирішило це для мене. Я намагався представити UIImagePickerController всередині блоку дій UIAlertAction.
josefdlange

функція alarView застаріла, чи буде це спрацьовувати, якщо я замість цього використовую асинхронію всередині дії UIAlertViewController?
DrPatience

@DrPatience Звичайно. dispatch_async працює будь-де, де ви хочете. Я не знаю, що це потрібно (залежатиме від вашого коду). Читайте на GCD - це дуже багато застосувань.
greg

12

У мене виникла ця проблема, коли анімація деяких переглядів і додаток перейде у фоновий режим і повернеться. Я обробляв це, встановлюючи прапор isActive. Я встановив його "НІ"

- (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
Я повністю спробував мій день! Я спробував вище методи, жоден не працював. І це спрацювало
Стен

Рішення не працює. Я думаю, коли ми знімаємо зображення в той час StatusBar вже приховано.
Міхір Оза

5

Я знайшов те саме питання і спробував усе. У мене є два різних додатки, одне в об'єктивному-C і одне в швидкому - обидва мають однакову проблему. Повідомлення про помилку надходить у відладчику, і екран стає чорним після першої фотографії. Це відбувається лише в iOS> = 8.0, очевидно, це помилка.

Я знайшов важке вирішення. Вимкніть елементи керування камерою за допомогою imagePicker.showsCameraControls = false та створіть власний overlayView, у якому відсутні кнопки. Існують різні підручники навколо того, як це зробити. Дивне повідомлення про помилку залишається, але принаймні екран не затьмарюється, і у вас є робоча програма.


У мене було те саме питання, що і у вас, дивіться мою відповідь нижче.
Ден

5

Це може бути помилка вбудованого ImagePickerController. Мій код працює, але час від часу виходить з ладу на iPhone 6 Plus.

Я спробував усі рішення, запропоновані іншими відповідями, але не пощастило. Проблема остаточно вирішена після переходу на JPSImagePickerController .


3

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

imagePicker.modalPresentationStyle = UIModalPresentationStyle.OverCurrentContext

3

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

Однак, функціонал все ще працює для мене. Окрім попередження / помилки, у вас є проблеми з функціонуванням вашої програми?


3

Якщо ми використовуємо UIImagePickerController властивість як властивість, то це попередження зникне.припустимо, що ми не використовуємо результат з 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 повертає істину, хоча я заборонив доступ до камери для свого додатка. Дисплей порожній, якщо доступ до камери заборонено.
Καrτhικ

1

Я зіткнувся з цим питанням. Коли ми зателефонуємо на камеру та звільнимо перегляди, викликані цією проблемою. Для прикладу зателефонуйте на камеру та встановіть view nil у методі viewDidDisappear, ця помилка настане, оскільки немає зворотного дзвінка для події камери. Переконайтеся і в цьому випадку про цю помилку.


1

Я отримав таку ж помилку, отримуючи нижче повідомлення в консолі під час відкриття камери.

"Знімок перегляду, який не було надано, призводить до порожнього знімка. Переконайтеся, що ваш перегляд був відображений принаймні один раз перед знімком або знімком після оновлення екрана. "

Для мене проблема полягала в тому, що відображуване ім'я пакета в файлі Info.plist було файлом пустим. Я поставив там своє ім'я програми, і тепер він працює добре. Я не отримав жодного попередження про дозвіл камери через порожнє відображення name.it заблокував подання перегляду.

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


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також не відображається помилка!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.