iOS 8 Snapshotting tampilan yang belum dirender menghasilkan snapshot kosong

228

Di iOS 8 saya mengalami masalah dalam mengambil gambar dari kamera sampai sekarang saya menggunakan kode ini untuk

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

Tetapi di iOS 8 saya mendapatkan ini:

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.

Saya telah mencoba dengan solusi yang disediakan oleh Posting ini dengan

@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];

dan ini

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

dan ini

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];
});

dan ini

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

dan ini

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

}];

ada ide?

souvickcse
sumber
3
Punya masalah yang sama dan lebih jauh lagi, bug ini membuat aplikasi saya sering rusak. Semoga pembaruan 8.0.2 akan memperbaiki bug ini. Ketika saya menjalankan aplikasi saya di iOS7 itu berfungsi seperti pesona tanpa peringatan bodoh. Sepertinya iOS 8 memiliki jalan panjang menuju stabilitas.
NCFUSN
9
Acara dengan pembaruan 8.0.2 masalah ini masih berlanjut
ArdenDev
2
Saya mengalami masalah yang sama. Setelah saya mengambil foto, saya melakukan beberapa pemrosesan di utas lainnya. Setelah saya memindahkan kode ke utas utama, maka semuanya baik-baik saja. Yaitu, kode saya sebelumnya adalah: dispatch_async(dispatch_get_main_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{yang saya ubah menjadidispatch_async(dispatch_get_main_queue(), ^{
mikeyq6
9
Masalah yang sama terjadi di iOS 8.1
Raptor
12
Terjadi di iOS 9 juga.
Sebyddd

Jawaban:

131

Saya cukup yakin ini hanya bug di iOS 8.0. Ini direproduksi dengan aplikasi POC paling sederhana yang tidak lebih dari upaya untuk menyajikan UIImagePickerControllerseperti yang Anda lakukan di atas. Selain itu, tidak ada pola alternatif untuk menampilkan pemilih gambar / kamera, setahu saya. Anda bahkan dapat mengunduh contoh aplikasi Apple Menggunakan UIImagePickerController , menjalankannya, dan itu akan menghasilkan kesalahan yang sama di luar kotak.

Yang mengatakan, fungsionalitasnya masih bekerja untuk saya. Selain peringatan / kesalahan, apakah Anda memiliki masalah dengan fungsi aplikasi Anda?

KevinH
sumber
2
Ya mungkin itu adalah bug, kode berfungsi dengan baik untuk saya juga.
souvickcse
4
@souvickcse Saya menemukan kesalahan ini juga. Setiap kali itu terjadi, pratinjau gambar yang muncul setelah gambar baru diambil sepenuhnya hitam. Namun, tombol "Ambil Kembali" dan "Gunakan Foto" di bagian bawah layar masih muncul dan berfungsi dengan baik. Apakah Anda menyaksikan perilaku yang sama ini?
Barry Beerman
3
@souvickcse Saya menggunakan baseline plugin kamera phonegap terbaru yang terletak di sini: github.com/apache/cordova-plugin-camera . Semuanya berfungsi dengan baik dengan iOS 7.1 yang berjalan pada iPhone 5 tetapi saya tidak dapat menemukan cara untuk membuatnya berfungsi dengan baik menggunakan iOS 8 pada iPhone 6.
Barry Beerman
2
Hal yang sama bagi saya dengan iOS8.1 final
fvisticot
4
Masih hadir di iOS 9
Pendeta
45

Saya berjuang dengan masalah ini selama beberapa jam, saya telah membaca setiap topik yang relevan dan menemukan bahwa kesalahan itu disebabkan karena di bawah pengaturan privasi perangkat saya, akses kamera ke aplikasi saya diblokir !!! Saya tidak pernah menyangkal akses ke kamera dan saya tidak tahu bagaimana itu diblokir tapi itu masalahnya!

Prosios Pantelis
sumber
4
Saya tidak yakin apakah itu benar-benar bekerja untuk Anda, tetapi itu tidak berhasil untuk saya. Saya hanya berharap @KevinH benar.
Deepak Thakur
4
Tidak, akses kamera diperiksa AKTIF untuk aplikasi itu dalam kasus saya. Tapi saya percaya ini bisa disebabkan walaupun secara tidak langsung oleh pengaturan: perubahan pada pengaturan kadang-kadang tidak langsung berlaku, seseorang di cupertino pasti telah mengoptimalkan panggilan untuk menyinkronkan di suatu tempat
Anton Tropashko
Saran ini menyelesaikan masalah bagi saya. Saya sebelumnya telah menyentuh "Don't Allow" ketika pemilih kamera muncul di aplikasi saya. Saya pikir itu akan bertanya setiap kali saya mengakses kamera, tetapi tidak. Saya harus pergi ke Pengaturan> Privasi> Kamera dan nyalakan slider untuk aplikasi saya. Kemudian itu bekerja dengan baik. Agak konyol di pihak Apple untuk tidak bertanya setiap kali ...
John Contarino
tepatnya, terkadang kita tidak bisa memikirkan masalah yang diangkat untuk jenis kesalahan ini. thx sobat sangat membantu
Mr.Javed Multani
Opsi terbaik adalah sebelum menggunakan kamera untuk mendeteksi apakah kemampuannya aktif, dan jika tidak, beri tahu pengguna bahwa pengambilan gambar tidak tersedia sampai kamera diaktifkan pada pengaturan. Di iOS 10, dimungkinkan untuk mengirim pengguna ke pengaturan aplikasi tertentu (dimungkinkan sebelum iOS 8, tetapi tidak mungkin di iOS 8 dan 9, jika saya ingat dengan benar).
kindaian
33

Saya tidak memiliki poin reputasi yang cukup untuk mengomentari jawaban @ greg di atas, jadi akan menambahkan pengamatan saya di sini. Saya memiliki proyek Swift untuk iPad dan iPhone. Saya memiliki metode di dalam pengontrol tampilan utama saya (bit yang relevan di bawah). Ketika saya menguji ini di telepon, semuanya berfungsi dengan baik dan tidak ada peringatan yang dihasilkan. Ketika saya menjalankannya di iPad, semuanya berfungsi dengan baik tetapi saya melihat peringatan tentang snapshotting tampilan. Yang menarik, bagaimanapun, adalah ketika saya menjalankan iPad tanpa menggunakan popover controller, semuanya bekerja dengan baik tanpa peringatan. Sayangnya, Apple mengamanatkan bahwa pemilih gambar harus digunakan dalam popover di iPad, jika kamera tidak digunakan.

    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
sumber
Sepertinya ini adalah saran yang benar karena saya mengalami pesan kesalahan itu bahkan dengan iOS 9.0.2. Saya memiliki aplikasi hanya iPhone dan ketika saya menjalankannya di iPad Mini saya, saya melihat pesan itu ketika menghadirkan pemilih gambar. Untuk beberapa alasan iOS berpikir bahwa saya menjalankan aplikasi iPad.
John Tracid
16

Saya mengalami hal ini setelah memanggil UIImagePickerController presentViewController: dari callback ke delegasi UIAlertView. Saya memecahkan masalah dengan mendorong presentViewController: membatalkan jejak eksekusi saat ini menggunakan 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
sumber
Inilah yang memecahkannya untuk saya. Saya mencoba untuk menyajikan UIImagePickerController dari dalam blok aksi UIAlertAction.
josefdlange
alertView telah ditinggalkan, apakah ini akan bekerja jika saya menggunakan async di dalam tindakan UIAlertViewController?
DrPatience
@Pratipatience Tentu. dispatch_async berfungsi di mana pun Anda inginkan. Saya tidak tahu bahwa itu perlu (akan tergantung kode Anda). Baca di GCD - ini memiliki banyak kegunaan.
greg
12

Saya mengalami masalah ini ketika menjiwai beberapa tampilan dan aplikasi akan masuk ke mode latar belakang dan kembali. Saya menanganinya dengan menetapkan bendera isActive. Saya mengaturnya untuk TIDAK di

- (void)applicationWillResignActive:(UIApplication *)application

dan YA dalam

- (void)applicationDidBecomeActive:(UIApplication *)application

dan menghidupkan atau tidak menghidupkan pandangan saya sesuai. Mengurus masalah ini.

byedissident
sumber
11

Saya punya ini dengan UIAlertControllerStyleActionSheet memberi pengguna pilihan untuk mengambil foto dengan kamera atau menggunakan satu dari perpustakaan.

Saya mencoba breakpoint simbolis pada pesan kesalahan masukkan deskripsi gambar di sini

Itu menunjukkan kepada saya kesalahan yang dihasilkan oleh penggunaan intern dari UICollectionView selama presentasi

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

masukkan deskripsi gambar di sini

Saya memperbaikinya dengan secara eksplisit mengatur frame sebelum presentasi

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

Berikut adalah metode lengkap yang berfungsi tanpa kesalahan

-(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
sumber
10

Anda dapat membungkam peringatan "Snapshotting a view" dengan mereferensikan viewproperti sebelum menghadirkan pengontrol tampilan. Melakukannya menyebabkan tampilan memuat dan memungkinkan iOS merendernya sebelum mengambil snapshot.

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];
Steve Shepard
sumber
Itu tip yang hampir sangat berguna. Terima kasih!!!! (Dalam kasus saya, saya masih mendapatkan peringatan, tetapi aplikasi tidak lagi macet.)
Fattie
Namun, ketika saya menambahkan cameraOverlayView, sayangnya saya masih mendapatkan masalah ini bahkan ketika saya menerapkan tip ini.
Fattie
8

Bagi siapa pun yang melihat masalah dengan pratinjau hitam setelah pengambilan gambar, menyembunyikan bilah status setelah UIPickerController ditampilkan tampaknya memperbaiki masalah tersebut.

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];
            }
        }];
Dan
sumber
1
benar-benar menyelamatkan hari saya! Saya telah mencoba metode di atas, tidak ada yang berhasil. Dan ini berhasil
Stan
Solusi tidak berfungsi. Saya pikir ketika kami mengambil gambar pada saat itu StatusBar sudah Tersembunyi.
Mihir Oza
5

Saya menemukan masalah yang sama dan mencoba segalanya. Saya memiliki dua aplikasi yang berbeda, satu di tujuan-C dan satu di cepat - keduanya memiliki masalah yang sama. Pesan kesalahan datang di debugger dan layar menjadi hitam setelah foto pertama. Ini hanya terjadi di iOS> = 8.0, jelas itu adalah bug.

Saya menemukan solusi yang sulit. Matikan kontrol kamera dengan imagePicker.showsCameraControls = false dan buat overlayView Anda sendiri yang memiliki tombol-tombol yang hilang. Ada berbagai tutorial seputar cara melakukan ini. Pesan kesalahan aneh tetap, tapi setidaknya layar tidak menjadi hitam dan Anda memiliki aplikasi yang berfungsi.

Thomas Zimmer
sumber
Saya memiliki masalah yang sama persis seperti Anda, lihat jawaban saya di bawah ini.
Dan
5

Ini mungkin bug dari ImagePickerController bawaan. Kode saya berfungsi, tetapi terkadang macet di iPhone 6 Plus.

Saya sudah mencoba semua solusi yang disarankan oleh jawaban lain tetapi tidak berhasil. Masalah akhirnya terpecahkan setelah beralih ke JPSImagePickerController .

JonSlowCN
sumber
3

Saya sudah mencoba semuanya, masalah saya adalah pemilih gambar untuk kamera dan perpustakaan foto menghilang tepat setelah mereka muncul. Saya menyelesaikannya dengan baris berikut (cepat)

imagePicker.modalPresentationStyle = UIModalPresentationStyle.OverCurrentContext
Waffeln
sumber
3

Saya cukup yakin ini hanya bug di iOS 8.0. Ini direproduksi dengan aplikasi POC paling sederhana yang tidak lebih dari upaya untuk menghadirkan UIImagePickerController seperti yang Anda lakukan di atas. Selain itu, tidak ada pola alternatif untuk menampilkan pemilih gambar / kamera, setahu saya. Anda bahkan dapat mengunduh contoh aplikasi Apple Menggunakan UIImagePickerController, menjalankannya, dan itu akan menghasilkan kesalahan yang sama di luar kotak.

Yang mengatakan, fungsionalitasnya masih bekerja untuk saya. Selain peringatan / kesalahan, apakah Anda memiliki masalah dengan fungsi aplikasi Anda?

Gaurav Patel
sumber
3

Jika kami menggunakan UIImagePickerControllersebagai properti, maka peringatan ini akan hilang.menganggap bahwa kita tidak menggunakan hasil dari UIImagePickerController, jika kita instantiating UIImagePickerControllerdalam suatu fungsi.

Antony Ouseph
sumber
2

Memanggil metode ini bekerja untuk saya. Tempatkan setelah menyajikan tampilan Anda.

[yourViewBeingPresented.view layoutIfNeeded];
Polisi
sumber
1

Saya juga mengalami masalah yang sama dan saya mengatasinya dengan memeriksa apakah kamera tersedia:

BOOL cameraAvailableFlag = [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera];
    if (cameraAvailableFlag)
        [self performSelector:@selector(showcamera) withObject:nil afterDelay:0.3];
aftab muhammed khan
sumber
1
isSourceTypeAvailable mengembalikan true meskipun saya telah menolak akses ke kamera untuk aplikasi saya. Tampilan kosong jika akses kamera ditolak.
Καrτhικ
1

Saya telah menemukan masalah ini. Ketika kami memanggil kamera dan melepaskan pandangan menghasilkan masalah ini. Misalnya, memanggil kamera dan mengatur tampilan nil dalam metode viewDidDisappear kesalahan ini akan terjadi karena tidak ada panggilan balik untuk acara kamera. Pastikan tentang kasus ini juga untuk kesalahan ini.

Gobi M
sumber
1

Saya mendapat bug yang sama, mendapatkan pesan di bawah di konsol sambil membuka kamera.

'Memotret ulang tampilan yang belum dirender menghasilkan snapshot kosong. Pastikan tampilan Anda telah diberikan setidaknya satu kali sebelum pengambilan gambar atau foto setelah pembaruan layar. '

Bagi saya masalah adalah dengan nama tampilan Bundle di Info.plist file.it itu kosong bagaimana, saya meletakkan nama aplikasi saya di sana dan sekarang berfungsi dengan baik. memblokir tampilan dari render.

masalahnya bukan pada tampilan tetapi dengan menghadirkannya tanpa izin. Anda dapat memeriksanya di pengaturan -> privasi -> Kamera, jika aplikasi Anda tidak terdaftar, masalahnya mungkin sama.

Ali Shabeer
sumber
1

Saya menggunakan Phonegap, tetapi utas ini terus muncul sebagai yang pertama saat Googling tentang pesan kesalahan.

Bagi saya masalah ini hilang dengan mendefinisikan imagetype ke PNG.

encodingType : Camera.EncodingType.PNG

Jadi seluruh barisnya adalah:

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

Jarak tempuh Anda mungkin berbeda-beda, tetapi itu cukup membantu saya.

Jannunen
sumber
1

Atau, pertimbangkan untuk menggunakan drawViewHierarchyInRect:

Cepat:

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

Tujuan-C:

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

    return image;
}

Lihat juga:

Eric
sumber
0

Dalam kasus saya (XCode 7 dan iOS 9), saya menggunakan UINavigationController"tersembunyi", jadi saya harus menambahkan UINavigationControllerDelegateuntuk menghadirkan kamera atau roll dan berfungsi seperti seharusnya! And pickerControllerDelegate.selfjuga tidak menampilkan kesalahan!

Daniel Arantes Loverde
sumber