PHAssets/PHAssetCollection/PHCollectionList 和文件夹
PHAssets/PHAssetCollection/PHCollectionList and Folders
我正在关注 Apple 的示例代码“ExampleappusingPhotosframework”。
在 PHAssets/PHAssetCollection 的主题中,我注意到可能存在“文件夹”。这些可以显示为 Mac 的照片应用程序或较旧的 iPhoto 应用程序等....
文件夹可能存在 PHAssetCollection 的数量,并且该文件夹可能包含未知级别的嵌套文件夹,最后以相册结尾。
所以,如果我在照片库中有嵌套文件夹,即使上面的示例项目也会崩溃。大多数应用程序似乎只是忽略并且根本不显示这些文件夹。
举个例子,假设这个例子存在:
文件夹级别 1 > 文件夹级别 2 > 自定义相册 > 图像 1、图像 2
iOS 照片应用如何处理它:
任务
在根相册列表中,在用户相册下,应该可以看到 "Folder Level 1"。点击后,我想列出所有子文件夹中的所有图像,而不考虑子级别......
viewDidLoad:
override func viewDidLoad() {
super.viewDidLoad()
let addButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(self.addAlbum))
self.navigationItem.rightBarButtonItem = addButton
// Create a PHFetchResult object for each section in the table view.
let allPhotosOptions = PHFetchOptions()
allPhotosOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: true)]
allPhotos = PHAsset.fetchAssets(with: allPhotosOptions)
smartAlbums = PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .albumRegular, options: nil)
userCollections = PHCollectionList.fetchTopLevelUserCollections(with: nil)
PHPhotoLibrary.shared().register(self)
}
cellForRowAt:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch Section(rawValue: indexPath.section)! {
case .allPhotos:
let cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifier.allPhotos.rawValue, for: indexPath)
cell.textLabel!.text = NSLocalizedString("All Photos", comment: "")
return cell
case .smartAlbums:
let cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifier.collection.rawValue, for: indexPath)
let collection = smartAlbums.object(at: indexPath.row)
cell.textLabel!.text = collection.localizedTitle
return cell
case .userCollections:
let cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifier.collection.rawValue, for: indexPath)
let collection = userCollections.object(at: indexPath.row)
cell.textLabel!.text = collection.localizedTitle
return cell
}
}
继续:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let destination = (segue.destination as? UINavigationController)?.topViewController as? AssetGridViewController
else { fatalError("unexpected view controller for segue") }
let cell = sender as! UITableViewCell
destination.title = cell.textLabel?.text
switch SegueIdentifier(rawValue: segue.identifier!)! {
case .showAllPhotos:
destination.fetchResult = allPhotos
case .showCollection:
// get the asset collection for the selected row
let indexPath = tableView.indexPath(for: cell)!
let collection: PHCollection
switch Section(rawValue: indexPath.section)! {
case .smartAlbums:
collection = smartAlbums.object(at: indexPath.row)
case .userCollections:
collection = userCollections.object(at: indexPath.row)
default: return // not reached; all photos section already handled by other segue
}
// configure the view controller with the asset collection
guard let assetCollection = collection as? PHAssetCollection
else { fatalError("expected asset collection") }
destination.fetchResult = PHAsset.fetchAssets(in: assetCollection, options: nil)
destination.assetCollection = assetCollection
}
}
问题
assetCollection?.canContainCollections 似乎是决定因素。但是,无论 sub-levels/sub-folders 如何获取文件夹中所有包含的 PHAssets? (这不可能是不可能的,因为即使股票应用程序在 1 级内也有 "All Photos")
使用当前的开发人员 API (PhotoKit) 没有简单的方法(例如使用单个请求)列出文件夹(及其 subfolders/albums)中的所有资产。但是,您可以递归枚举文件夹及其子文件夹中的所有相册,然后将结果放入一个数组中。然而,这可能会很慢,具体取决于嵌套结构中包含的级别和资产的数量。
请注意,任何级别的文件夹也可以包含相册(例如,在 "Folder Level 1" 上,除了文件夹 "Folder Level 2" 之外还可能有相册)。
Apple 的照片应用程序没有使用 PhotoKit - 所以我认为他们有办法通过单个请求来完成此操作。
我正在关注 Apple 的示例代码“ExampleappusingPhotosframework”。
在 PHAssets/PHAssetCollection 的主题中,我注意到可能存在“文件夹”。这些可以显示为 Mac 的照片应用程序或较旧的 iPhoto 应用程序等....
文件夹可能存在 PHAssetCollection 的数量,并且该文件夹可能包含未知级别的嵌套文件夹,最后以相册结尾。
所以,如果我在照片库中有嵌套文件夹,即使上面的示例项目也会崩溃。大多数应用程序似乎只是忽略并且根本不显示这些文件夹。
举个例子,假设这个例子存在:
文件夹级别 1 > 文件夹级别 2 > 自定义相册 > 图像 1、图像 2
iOS 照片应用如何处理它:
任务
在根相册列表中,在用户相册下,应该可以看到 "Folder Level 1"。点击后,我想列出所有子文件夹中的所有图像,而不考虑子级别......
viewDidLoad:
override func viewDidLoad() {
super.viewDidLoad()
let addButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(self.addAlbum))
self.navigationItem.rightBarButtonItem = addButton
// Create a PHFetchResult object for each section in the table view.
let allPhotosOptions = PHFetchOptions()
allPhotosOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: true)]
allPhotos = PHAsset.fetchAssets(with: allPhotosOptions)
smartAlbums = PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .albumRegular, options: nil)
userCollections = PHCollectionList.fetchTopLevelUserCollections(with: nil)
PHPhotoLibrary.shared().register(self)
}
cellForRowAt:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch Section(rawValue: indexPath.section)! {
case .allPhotos:
let cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifier.allPhotos.rawValue, for: indexPath)
cell.textLabel!.text = NSLocalizedString("All Photos", comment: "")
return cell
case .smartAlbums:
let cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifier.collection.rawValue, for: indexPath)
let collection = smartAlbums.object(at: indexPath.row)
cell.textLabel!.text = collection.localizedTitle
return cell
case .userCollections:
let cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifier.collection.rawValue, for: indexPath)
let collection = userCollections.object(at: indexPath.row)
cell.textLabel!.text = collection.localizedTitle
return cell
}
}
继续:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let destination = (segue.destination as? UINavigationController)?.topViewController as? AssetGridViewController
else { fatalError("unexpected view controller for segue") }
let cell = sender as! UITableViewCell
destination.title = cell.textLabel?.text
switch SegueIdentifier(rawValue: segue.identifier!)! {
case .showAllPhotos:
destination.fetchResult = allPhotos
case .showCollection:
// get the asset collection for the selected row
let indexPath = tableView.indexPath(for: cell)!
let collection: PHCollection
switch Section(rawValue: indexPath.section)! {
case .smartAlbums:
collection = smartAlbums.object(at: indexPath.row)
case .userCollections:
collection = userCollections.object(at: indexPath.row)
default: return // not reached; all photos section already handled by other segue
}
// configure the view controller with the asset collection
guard let assetCollection = collection as? PHAssetCollection
else { fatalError("expected asset collection") }
destination.fetchResult = PHAsset.fetchAssets(in: assetCollection, options: nil)
destination.assetCollection = assetCollection
}
}
问题
assetCollection?.canContainCollections 似乎是决定因素。但是,无论 sub-levels/sub-folders 如何获取文件夹中所有包含的 PHAssets? (这不可能是不可能的,因为即使股票应用程序在 1 级内也有 "All Photos")
使用当前的开发人员 API (PhotoKit) 没有简单的方法(例如使用单个请求)列出文件夹(及其 subfolders/albums)中的所有资产。但是,您可以递归枚举文件夹及其子文件夹中的所有相册,然后将结果放入一个数组中。然而,这可能会很慢,具体取决于嵌套结构中包含的级别和资产的数量。 请注意,任何级别的文件夹也可以包含相册(例如,在 "Folder Level 1" 上,除了文件夹 "Folder Level 2" 之外还可能有相册)。 Apple 的照片应用程序没有使用 PhotoKit - 所以我认为他们有办法通过单个请求来完成此操作。