为啥在应用程序的初始启动过程中没有出现照片?

Posted

技术标签:

【中文标题】为啥在应用程序的初始启动过程中没有出现照片?【英文标题】:Why don't the photos appear during the initial launch of the app?为什么在应用程序的初始启动过程中没有出现照片? 【发布时间】:2018-04-11 01:19:39 【问题描述】:

我已经实现了一个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!
    

【问题讨论】:

我认为您需要在用户允许访问他的库后重新获取照片。重新启动时,提取会立即生效,因为用户已经允许访问他的图片。 如果您可以制作一个新屏幕只是为了请求访问照片并解释您为什么需要它。当您获得访问权限时,您会关闭视图并显示您的收藏。或请求访问,当您获得允许访问的完成块时,重新执行获取(出于安全原因,请确保在主线程上调用它) 让我们在应用激活时尝试重新加载数据 【参考方案1】:

首先检查您是否有权限。如果您仅被授权,则初始化 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() 中调用此方法。希望这会有所帮助。

【讨论】:

【参考方案2】:

viewDidAppear重新加载你的collectionView,应用程序请求用户权限后,viewDidAppear方法会调用。

colllectionView.reloadData()

【讨论】:

以上是关于为啥在应用程序的初始启动过程中没有出现照片?的主要内容,如果未能解决你的问题,请参考以下文章

为啥启动rviz没有机器人出现

为啥电脑一开机后CPU使用量就是100%?

为啥rabbitMQ启动特别慢

为啥在iOS模拟器中实际启动屏幕出现之前会出现白屏

WORKBENCH,启动后,toolox窗口出现no toolbox items are applicable for the current selection这是为啥

安装完IE8以后为啥每次启动IE都会出现那个该死的对话框?