Почему не отображаются фотографии при первом запуске приложения?

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

Ниже приведен код viewController, о котором идет речь.

import UIKit
import Photos

class ViewController: UIViewController,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout,UICollectionViewDataSource {

    var imageArray:[UIImage] = [UIImage]()

    var collectionView:UICollectionView! = {
        let layout = UICollectionViewFlowLayout()
        layout.minimumInteritemSpacing = 1
        layout.minimumLineSpacing = 1
        layout.scrollDirection = .vertical
        let CV = UICollectionView(frame: UIScreen.main.bounds, collectionViewLayout: layout)
        CV.translatesAutoresizingMaskIntoConstraints = false
        return CV
    }()

    var fetchResult: PHFetchResult<PHAsset> = PHFetchResult()

    override func viewDidLoad() {
        super.viewDidLoad()
        self.collectionView.delegate = self
        self.collectionView.dataSource = self
        collectionView.register(customPhotoCell.self, forCellWithReuseIdentifier: "Cell")
        self.view.addSubview(collectionView)
        setUpLayout()
        fetchAssets()
    }

    func setUpLayout(){
        collectionView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 50).isActive = true
        collectionView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: 0).isActive = true
        collectionView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: 0).isActive = true
        collectionView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 0).isActive = true
    }

    func fetchAssets(){
        let fetchOptions = PHFetchOptions()
        fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
        fetchResult = PHAsset.fetchAssets(with: .image, options: fetchOptions)
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return fetchResult.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! customPhotoCell
        let imageView = cell.imgView
        let requestOptions = PHImageRequestOptions()
        requestOptions.isSynchronous = true
        requestOptions.deliveryMode = .highQualityFormat
        PHImageManager.default().requestImage(for: fetchResult.object(at: indexPath.item) , targetSize: CGSize(width: 200,height: 200), contentMode: .aspectFill, options: requestOptions, resultHandler: {
            image,error in
            if let error = error{
                print(error)
            }
            self.imageArray.append(image!)
            imageView.image = image!
        })
        return cell
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        return 1
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
        return 1
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let width = self.view.bounds.width/3 - 1
        return CGSize(width: width, height: width)
    }

}

class customPhotoCell:UICollectionViewCell{

    var imgView:UIImageView = {
        let imgV = UIImageView()
        imgV.backgroundColor = .orange
        imgV.translatesAutoresizingMaskIntoConstraints = false
        return imgV
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.addSubview(imgView)
        imgView.topAnchor.constraint(equalTo: self.topAnchor, constant: 0).isActive = true
        imgView.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 0).isActive = true
        imgView.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 0).isActive = true
        imgView.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: 0).isActive = true
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}

extension UIImageView{
    func fetchImage(asset: PHAsset, contentMode: PHImageContentMode, targetSize: CGSize) {
        let options = PHImageRequestOptions()
        options.version = .original
        PHImageManager.default().requestImage(for: asset, targetSize: targetSize, contentMode: contentMode, options: options) { image, _ in
            guard let image = image else { return }
            switch contentMode {
            case .aspectFill:
                self.contentMode = .scaleAspectFill
            case .aspectFit:
                self.contentMode = .scaleAspectFit
            }
            self.image = image
        }
    }
}

extension UIImage{
    func resizeImageWith() -> UIImage {
        let aspectRatio = CGFloat(self.size.width / self.size.height)
        let newWidth = UIScreen.main.bounds.width
        let newSize = CGSize(width: newWidth, height: newWidth/aspectRatio)
        UIGraphicsBeginImageContextWithOptions(newSize, true, 0)
        self.draw(in: CGRect(origin: CGPoint(x: 0, y: 0), size: newSize))
        let  newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return newImage!
    }
}

person TheRedCamaro3.0 3.0    schedule 11.04.2018    source источник
comment
Я думаю, вам нужно повторно загрузить фотографии после того, как пользователи предоставят доступ к его библиотеке. При перезапуске выборка срабатывает сразу, т.к. пользователь УЖЕ дал доступ к своим картинкам.   -  person Mikael    schedule 11.04.2018
comment
Если можно сделать новый скрин просто попросить доступ к фоткам и объяснить зачем он нужен. и когда вы получаете доступ, вы закрываете представление и показываете свою коллекцию. ИЛИ запросите доступ, и когда вы получите блок завершения с разрешенным доступом, повторите выборку (убедитесь, что вы вызываете ее в основном потоке по соображениям безопасности)   -  person Mikael    schedule 11.04.2018
comment
давайте попробуем перезагрузить данные, когда приложение станет активным   -  person Scott.N    schedule 11.04.2018


Ответы (2)


Сначала проверьте, есть ли у вас разрешение или нет. Если вы авторизованы, только тогда инициализируйте fetchResult и перезагрузите collectionView.

func checkPhotoLibraryPermission() {
    let status = PHPhotoLibrary.authorizationStatus()
    switch status {
    case .authorized:
        self.fetchAssets()
        self.cv.reloadData()
    case .denied, .restricted : break
    //handle denied status
    case .notDetermined:
        // ask for permissions
        PHPhotoLibrary.requestAuthorization() { status in
            switch status {
            case .authorized:
                DispatchQueue.main.async {
                    self.fetchAssets()
                    self.cv.reloadData()
                }
            // as above
            case .denied, .restricted: break
            // as above
            case .notDetermined: break
                // won't happen but still
            }
        }
    }

Вызовите этот метод в viewDidLoad() вместо fetchAssets(). Надеюсь это поможет.

person Chanchal Chauhan    schedule 11.04.2018

Перезагрузите свой collectionView в viewDidAppear, после того как приложение запросит разрешение пользователей, вызовет метод viewDidAppear.

colllectionView.reloadData()
person Naren Krish    schedule 11.04.2018