Представление коллекции не перезагружается (Swift)

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

Нажата кнопка «Новая фотография» -> Пользователю предоставляется контроллер представления UICollection со всеми фотографиями из его библиотеки и возможностью выбора нескольких фотографий (я повторно использую ячейку для заполнения этого представления коллекции изображениями из библиотеки фотографий) и над этим должна быть ячейка Камера (пользователю нужно нажать на кнопку, чтобы разрешить доступ к камере, чтобы сделать снимок). Вот представление из Симулятора.

введите здесь описание изображения

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

Что для этого нужно сделать. Когда пользователю предлагается предоставить доступ к фотографиям и он нажимает "ОК", он должен перезагрузить данные в представлении коллекции, но этого не происходит. И когда они нажимают «Не разрешать», он должен закрыть весь контроллер представления. Вот мой код

class CVController: UICollectionViewController, UINavigationControllerDelegate, UICollectionViewDelegateFlowLayout {

var photosLibraryArray = [UIImage]()

override func viewDidLoad() {
    super.viewDidLoad()

    grabAllPhotosFromPhoneLibrary()

}

// Grab All Photos from Library
func grabAllPhotosFromPhoneLibrary () {

    let imageManager = PHImageManager.default()

    let requestOptions = PHImageRequestOptions()
    requestOptions.isSynchronous = true  // synchronous works better when grabbing all images
    requestOptions.deliveryMode = .opportunistic

    let fetchOptions = PHFetchOptions()
    fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: true)] // if false = last image we took would show first

    let fetchResult: PHFetchResult = PHAsset.fetchAssets(with: .image, options: fetchOptions)

    // 1. Are there photos in the library
    if fetchResult.count > 0 {

        // 2. if fetch.count > 0 it means there's at least 1 photo in the library
        for i in 0..<fetchResult.count {

            // 3. Cycling through the photos
            imageManager.requestImage(for: fetchResult.object(at: i), targetSize: CGSize(width: 200, height: 200), contentMode: .aspectFill, options: requestOptions, resultHandler:

                { image, error in
                    // 4. Append each image in the array
                    self.photosLibraryArray.append(image!)
            })
        }

    } else {
        print("You've got no photos")
        self.collectionView?.reloadData()
    }

Пробовал звонить collectionView.reloadData() в viewWillApear(), viewDidApear(), ничего не получилось.


person Dani    schedule 11.05.2017    source источник
comment
Из приведенного выше кода вы вызываете reloadData() только тогда, когда нет фотографий.   -  person adamfowlerphoto    schedule 11.05.2017
comment
Используйте этот self.collectionView?.reloadData(), где вы получаете событие для OK.   -  person Prateekro    schedule 11.05.2017
comment
@Spads Я не публиковал реализации, потому что, по моему скромному мнению, в них нет особой необходимости. Я мог бы, если вам это тоже нужно, но он содержит некоторую базовую реализацию количества разделов, количества элементов в разделе и ячейки для элемента. Изображения действительно загружаются, как показано на снимке экрана в симуляторе, но это происходит только при повторном запуске приложения после предоставления доступа к фотографиям.   -  person Dani    schedule 11.05.2017


Ответы (1)


    class CVController: UICollectionViewController, UINavigationControllerDelegate, UICollectionViewDelegateFlowLayout {

    var photosLibraryArray = [UIImage]()

    override func viewDidLoad() {
    super.viewDidLoad()

        checkPhotoLibraryPermission()
    }

Добавьте эту нижеупомянутую функцию

    func checkPhotoLibraryPermission() {
        let status = PHPhotoLibrary.authorizationStatus()
        switch status {
        case .authorized: 
        //handle authorized status - // call this function here
                grabAllPhotosFromPhoneLibrary()
            case .denied, .restricted : 
                //handle denied status
            case .notDetermined: 
                // ask for permissions
                PHPhotoLibrary.requestAuthorization() { status in
                    switch status {
                    case .authorized: 
                        // call this function here
                        grabAllPhotosFromPhoneLibrary()

                    case .denied, .restricted: 
                        // as above
                        _ = navigationController?.popViewController(animated: true)
                    case .notDetermined: 
                        // won't happen but still, if you want to handle.
                }
        }
    }
    }

Соответственно, вы можете внести изменения в следующую функцию ниже. По необходимости.

    // Grab All Photos from Library
    func grabAllPhotosFromPhoneLibrary () {

    let imageManager = PHImageManager.default()

    let requestOptions = PHImageRequestOptions()
    requestOptions.isSynchronous = true  // synchronous works better when grabbing all images
    requestOptions.deliveryMode = .opportunistic

    let fetchOptions = PHFetchOptions()
    fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: true)] // if false = last image we took would show first

    let fetchResult: PHFetchResult = PHAsset.fetchAssets(with: .image, options: fetchOptions)

    // 1. Are there photos in the library
    if fetchResult.count > 0 {

        // 2. if fetch.count > 0 it means there's at least 1 photo in the library
        for i in 0..<fetchResult.count {

            // 3. Cycling through the photos
            imageManager.requestImage(for: fetchResult.object(at: i), targetSize: CGSize(width: 200, height: 200), contentMode: .aspectFill, options: requestOptions, resultHandler:

                { image, error in
                    // 4. Append each image in the array
                    self.photosLibraryArray.append(image!)
            })
        }
    //Use this reload data here as - you want the data loaded in the array first and then show the data.

    self.collectionView?.reloadData()

    } else {
        print("You've got no photos")
        //self.collectionView?.reloadData()

        // if you want to hide the view controller when there is no photo. pop the view controller from your navigation controller like this. 

     _ = navigationController?.popViewController(animated: true)
    }
person Prateekro    schedule 11.05.2017
comment
@Swifter Это помогло? - person Prateekro; 11.05.2017
comment
Нет. Все еще не работает. Кроме того, эта функция grabAllPhotosFromPhoneLibrary() вызывается в viewDidLoad(), так что это первое, что вызывается при загрузке представления. Итак, возникает проблема, если пользователь не предоставил доступ к фотографиям да. Когда вы загружаете приложение в первый раз, оно переходит к оператору else и никогда не выполняет оператор if, если только вы не закроете приложение и не запустите его снова. Что вызывается, когда пользователь разрешает доступ к фотографиям? Я пробовал с viewDidLoad(), viewDidAppear() и звонил туда self.collectionView?.reloadData(), но это не сработало - person Dani; 11.05.2017
comment
Проверьте обновленный ответ. И дайте мне знать, если возник конфликт. Хотя это не проверено. Я думаю, что больше всего я справился в checkPhotoLibraryPermission() - person Prateekro; 11.05.2017