照片未显示在收藏夹视图中

Posted

技术标签:

【中文标题】照片未显示在收藏夹视图中【英文标题】:Photos not showing in collection view 【发布时间】:2016-09-23 15:15:20 【问题描述】:

当我打开我的应用程序时,它会询问我是否有权访问我的照片。没关系。但是接受后,屏幕变黑并且没有照片,并且在我的控制台中它说它没有找到照片。虽然我的设备上有照片。

import UIKit
import Photos

class ViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout 
    var imageArray = [UIImage]()

    override func viewDidLoad() 
        grabPhotos()
    

    func grabPhotos()
        let imgManager = PHImageManager.defaultManager()

        let requestOptions = PHImageRequestOptions()
        requestOptions.synchronous = true
        requestOptions.deliveryMode = .HighQualityFormat

        let fetchOptions = PHFetchOptions()
        fetchOptions.sortDescriptors = [NSSortDescriptor(key:"CreationDate" , ascending: false)]

        if let fetchResult : PHFetchResult = PHAsset.fetchAssetsWithMediaType(.Image, options: fetchOptions)
            if fetchResult.count > 0 
                for i in 0..<fetchResult.count
                    imgManager.requestImageForAsset(fetchResult.objectAtIndex(i) as! PHAsset, targetSize: CGSize(width: 200, height: 200), contentMode: .AspectFill, options: requestOptions, resultHandler: 

                        image, error in

                        self.imageArray.append(image!)
                    )
                
            
            else
                print("You have got not photos!")
                self.collectionView?.reloadData()
            
        
    

    override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
        return imageArray.count
    

    override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell 
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath)

        let imageView = cell.viewWithTag(1) as! UIImageView

        imageView.image = imageArray[indexPath.row]

        return cell
    

    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize 
        let width = collectionView.frame.width / 3 - 1

        return CGSize(width: width, height: width)
    

    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat 
        return 1.0
    

    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat 
        return 1.0
    

【问题讨论】:

我看到你在 cellForItem 方法中使用了 cell.viewWithTag(1)。您知道如何为您的 tableView 创建一个单元格原型,以便您可以设计您的单元格并将其与图像内容连接起来吗? 【参考方案1】:

这里的问题很可能是您只请求一次资产。你第一次问,你什么都得不到。当您调用PHAsset.fetchAssetsWithMediaType 时,它同时做两件事:它要求用户授权,并且由于尚未授予授权(授权提示仍在屏幕上),它返回一个空的提取结果。 (而且因为获取结果是空的,所以不能

如果这是问题所在,您应该会在第二次运行应用时看到一个非空的提取结果(因为授权是一次性的,并且会在启动时持续存在)。

有几种方法可以解决这个问题...

一种方法是先使用requestAuthorization() 直接请求授权,然后仅在该调用的完成处理程序触发(结果为肯定)后获取资产。

另一个是register()您的视图控制器(或您的其他控制器类)在执行获取之前作为照片库的观察者。您在授权之前的第一次提取仍然返回一个空结果,但是一旦用户授权您的应用,您的观察者就会收到一个 photoLibraryDidChange() 调用,您可以从中访问完整的“真实”提取结果。


除此之外,您正在做的其他一些事情不是最佳实践...

您从PHImageManager 请求库中每个资产的图像,无论用户是否会看到它们。考虑一个 iCloud 照片库包含数以万计资产的人的情况——只有前 30 个左右会一次适合您的收藏视图,用户可能永远不会一直滚动到最后,但您仍在为每个图像获取缩略图。 (如果 iCloud 资产不在本地设备上,则会触发网络活动以获取用户可能永远看不到的大量缩略图。)

您将从PHImageManager 同步并按顺序获取缩略图。一旦处理了授权问题,您的应用程序可能会崩溃,因为您的 for i in 0..&lt;fetchResult.count imgManager.requestImageForAsset 循环阻塞主线程太久。

Apple 提供了canonical example code,该canonical example code 演示了如何使用“照片”应用来执行诸如显示充满缩略图的集合视图之类的操作。看看那个项目中的AssetGridViewController.swift,看看他们正在做的一些事情:

使用PHCachingImageManager根据集合视图的可见区域预取批量缩略图 使用phphotoLibraryObserver 对提取结果中的更改做出反应,包括动画集合视图更新 处理异步获取和集合视图数据源之间的交互 在照片库中插入新资源

【讨论】:

【参考方案2】:

1) 子类 UICollectionViewCell:

import ...
//put this e.g. to the top of your swift file, right after import statements

class PhotoViewCell: UICollectionViewCell 

    @IBOutlet weak var myImageView: UIImageView! 


2) 为您的单元创建原型

2.1 设计它(你可能以前做过)

2.2输入标识符

2.3进入班级

2.4 CTRL 从情节提要拖动:从单元格的 imageView 到 @IBOutlet 行(从步骤 1 开始)

3) 更新您的 cellForItem 方法

let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCell", for: indexPath) as! PhotoViewCell 

    cell.myImageView.image = imageArray[indexPath.row]
    return cell

【讨论】:

【参考方案3】:

为 cell 使用一个类,将 imageview 放在你的 cell 中使其成为一个出口

现在写这个

override func collectionView(collectionView: UICollectionView,      cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell 

let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as! 'your class name for cell'

cell.Image.image = imageArray[indexPath.row]

return cell




【讨论】:

以上是关于照片未显示在收藏夹视图中的主要内容,如果未能解决你的问题,请参考以下文章

Facebook 在 uitableview 中加载相册,但未在下一个收藏视图中打开

将收藏夹功能添加到 iPhone App iphone sdk

收藏视图编辑菜单未出现

Sonata Admin Bundle:在列表视图中显示收藏总数

如何在收藏视图中显示复选标记(图像)

收藏的内容未在 webview 上正确显示