From 896e2f4462367a5ceaccc8a366183e4659f29642 Mon Sep 17 00:00:00 2001 From: "naoto.suzuki" Date: Mon, 8 Nov 2021 14:02:03 +0900 Subject: [PATCH 01/26] Added selectable view. --- Demo/DemoListViewController.swift | 8 +++++ NohanaImagePicker.xcodeproj/project.pbxproj | 4 +++ .../AlbumListViewController.swift | 19 ++++++++-- .../AssetListSelectableDateSection.storyboard | 35 +++++++++++++++++++ .../NohanaImagePicker.storyboard | 15 +++++++- .../NohanaImagePickerController.swift | 1 + 6 files changed, 78 insertions(+), 4 deletions(-) create mode 100644 NohanaImagePicker/AssetListSelectableDateSection.storyboard diff --git a/Demo/DemoListViewController.swift b/Demo/DemoListViewController.swift index f8f05c8..5336d48 100644 --- a/Demo/DemoListViewController.swift +++ b/Demo/DemoListViewController.swift @@ -30,6 +30,7 @@ class DemoListViewController: UITableViewController, NohanaImagePickerController Cell(title: "No toolbar", selector: #selector(DemoListViewController.showNoToolbarPicker)), Cell(title: "Disable to pick assets", selector: #selector(DemoListViewController.showDisableToPickAssetsPicker)), Cell(title: "Custom UI", selector: #selector(DemoListViewController.showCustomUIPicker)), + Cell(title: "Selectable Album Date Section", selector: #selector(DemoListViewController.showSelectableDateSectionPicker)), ] override func viewDidAppear(_ animated: Bool) { @@ -136,6 +137,13 @@ class DemoListViewController: UITableViewController, NohanaImagePickerController present(picker, animated: true, completion: nil) } + @objc func showSelectableDateSectionPicker() { + let picker = NohanaImagePickerController() + picker.canPickDateSection = true + picker.delegate = self + present(picker, animated: true, completion: nil) + } + // MARK: - NohanaImagePickerControllerDelegate func nohanaImagePickerDidCancel(_ picker: NohanaImagePickerController) { diff --git a/NohanaImagePicker.xcodeproj/project.pbxproj b/NohanaImagePicker.xcodeproj/project.pbxproj index 5ec541b..f058597 100644 --- a/NohanaImagePicker.xcodeproj/project.pbxproj +++ b/NohanaImagePicker.xcodeproj/project.pbxproj @@ -9,6 +9,7 @@ /* Begin PBXBuildFile section */ 3569CAA91EC1918E000C41C0 /* NohanaImagePicker.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3569CAA61EC1918E000C41C0 /* NohanaImagePicker.xcassets */; }; F181095026A5361A001C2BDE /* MomentDetailListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F181094F26A5361A001C2BDE /* MomentDetailListViewController.swift */; }; + F1A26CCD2738DE6A00433E9F /* AssetListSelectableDateSection.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F1A26CCC2738DE6A00433E9F /* AssetListSelectableDateSection.storyboard */; }; F1E5DE7D26A57F0B004B9EDE /* DetailListViewControllerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1E5DE7C26A57F0B004B9EDE /* DetailListViewControllerProtocol.swift */; }; F1E5DE8026A58346004B9EDE /* MomentInfoSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1E5DE7F26A58346004B9EDE /* MomentInfoSection.swift */; }; F1E5DE8226A58386004B9EDE /* MomentInfoSectionCreater.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1E5DE8126A58386004B9EDE /* MomentInfoSectionCreater.swift */; }; @@ -78,6 +79,7 @@ 3569CAA61EC1918E000C41C0 /* NohanaImagePicker.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = NohanaImagePicker.xcassets; sourceTree = ""; }; 3590F1F51EC1A79400F32E06 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/NohanaImagePicker.strings; sourceTree = ""; }; F181094F26A5361A001C2BDE /* MomentDetailListViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MomentDetailListViewController.swift; sourceTree = ""; }; + F1A26CCC2738DE6A00433E9F /* AssetListSelectableDateSection.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = AssetListSelectableDateSection.storyboard; sourceTree = ""; }; F1E5DE7C26A57F0B004B9EDE /* DetailListViewControllerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailListViewControllerProtocol.swift; sourceTree = ""; }; F1E5DE7F26A58346004B9EDE /* MomentInfoSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MomentInfoSection.swift; sourceTree = ""; }; F1E5DE8126A58386004B9EDE /* MomentInfoSectionCreater.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MomentInfoSectionCreater.swift; sourceTree = ""; }; @@ -188,6 +190,7 @@ isa = PBXGroup; children = ( F23554251C69D19C00796DCA /* NohanaImagePicker.storyboard */, + F1A26CCC2738DE6A00433E9F /* AssetListSelectableDateSection.storyboard */, F27029CD1C71C43A001647AB /* NohanaImagePicker.strings */, F237249A1C6DCF96005D1E8A /* NohanaImagePicker.xcassets */, ); @@ -388,6 +391,7 @@ F23554261C69D19C00796DCA /* NohanaImagePicker.storyboard in Resources */, F27029CB1C71C43A001647AB /* NohanaImagePicker.strings in Resources */, F237249B1C6DCF96005D1E8A /* NohanaImagePicker.xcassets in Resources */, + F1A26CCD2738DE6A00433E9F /* AssetListSelectableDateSection.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/NohanaImagePicker/AlbumListViewController.swift b/NohanaImagePicker/AlbumListViewController.swift index 5b2ac42..930f003 100644 --- a/NohanaImagePicker/AlbumListViewController.swift +++ b/NohanaImagePicker/AlbumListViewController.swift @@ -83,6 +83,11 @@ class AlbumListViewController: UITableViewController, EmptyIndicatable, Activity nohanaImagePickerController.delegate?.nohanaImagePickerDidSelectMoment?(nohanaImagePickerController) case .albums: nohanaImagePickerController.delegate?.nohanaImagePicker?(nohanaImagePickerController, didSelectPhotoKitAssetList: photoKitAlbumList[indexPath.row].assetList) + if nohanaImagePickerController.canPickDateSection { + performSegue(withIdentifier: "toAssetListViewSelectableDateSectionController", sender: nil) + } else { + performSegue(withIdentifier: "toAssetListViewController", sender: nil) + } } } @@ -184,9 +189,17 @@ class AlbumListViewController: UITableViewController, EmptyIndicatable, Activity let momentViewController = segue.destination as! MomentViewController momentViewController.nohanaImagePickerController = nohanaImagePickerController case .albums: - let assetListViewController = segue.destination as! AssetListViewController - assetListViewController.photoKitAssetList = photoKitAlbumList[tableView.indexPathForSelectedRow!.row] - assetListViewController.nohanaImagePickerController = nohanaImagePickerController + switch segue.identifier { + case "toAssetListViewController": + let assetListViewController = segue.destination as! AssetListViewController + assetListViewController.photoKitAssetList = photoKitAlbumList[tableView.indexPathForSelectedRow!.row] + assetListViewController.nohanaImagePickerController = nohanaImagePickerController + case "toAssetListViewSelectableDateSectionController": + // TODO + print("show selectable view") + default: + fatalError("unexpected segue identifer") + } } } diff --git a/NohanaImagePicker/AssetListSelectableDateSection.storyboard b/NohanaImagePicker/AssetListSelectableDateSection.storyboard new file mode 100644 index 0000000..bc0e3e3 --- /dev/null +++ b/NohanaImagePicker/AssetListSelectableDateSection.storyboard @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/NohanaImagePicker/NohanaImagePicker.storyboard b/NohanaImagePicker/NohanaImagePicker.storyboard index 986a9e1..0a1dd81 100644 --- a/NohanaImagePicker/NohanaImagePicker.storyboard +++ b/NohanaImagePicker/NohanaImagePicker.storyboard @@ -49,7 +49,6 @@ - @@ -96,6 +95,10 @@ + + + + @@ -513,6 +516,16 @@ + + + + + + + + + + diff --git a/NohanaImagePicker/NohanaImagePickerController.swift b/NohanaImagePicker/NohanaImagePickerController.swift index ffea723..2856ef1 100644 --- a/NohanaImagePicker/NohanaImagePickerController.swift +++ b/NohanaImagePicker/NohanaImagePickerController.swift @@ -50,6 +50,7 @@ open class NohanaImagePickerController: UIViewController { return true } open var config: Config = Config() + open var canPickDateSection: Bool = false lazy var assetBundle: Bundle = { let bundle = Bundle(for: type(of: self)) From 625305c3037ad6d907e4adc00d1cf706fa8b35cd Mon Sep 17 00:00:00 2001 From: "naoto.suzuki" Date: Mon, 8 Nov 2021 17:55:29 +0900 Subject: [PATCH 02/26] Added selectable date section view. --- NohanaImagePicker.xcodeproj/project.pbxproj | 12 + NohanaImagePicker/AlbumDateSection.swift | 22 ++ .../AlbumDateSectionHeaderView.swift | 21 ++ .../AlbumListViewController.swift | 5 +- .../AssetListSelectableDateSection.storyboard | 133 ++++++++-- ...tListSelectableDateSectionController.swift | 229 ++++++++++++++++++ 6 files changed, 399 insertions(+), 23 deletions(-) create mode 100644 NohanaImagePicker/AlbumDateSection.swift create mode 100644 NohanaImagePicker/AlbumDateSectionHeaderView.swift create mode 100644 NohanaImagePicker/AssetListSelectableDateSectionController.swift diff --git a/NohanaImagePicker.xcodeproj/project.pbxproj b/NohanaImagePicker.xcodeproj/project.pbxproj index f058597..498d644 100644 --- a/NohanaImagePicker.xcodeproj/project.pbxproj +++ b/NohanaImagePicker.xcodeproj/project.pbxproj @@ -10,6 +10,9 @@ 3569CAA91EC1918E000C41C0 /* NohanaImagePicker.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3569CAA61EC1918E000C41C0 /* NohanaImagePicker.xcassets */; }; F181095026A5361A001C2BDE /* MomentDetailListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F181094F26A5361A001C2BDE /* MomentDetailListViewController.swift */; }; F1A26CCD2738DE6A00433E9F /* AssetListSelectableDateSection.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F1A26CCC2738DE6A00433E9F /* AssetListSelectableDateSection.storyboard */; }; + F1A26CCF2738E7E400433E9F /* AssetListSelectableDateSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1A26CCE2738E7E400433E9F /* AssetListSelectableDateSectionController.swift */; }; + F1A26CD12738E88700433E9F /* AlbumDateSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1A26CD02738E88700433E9F /* AlbumDateSection.swift */; }; + F1A26CD32739194300433E9F /* AlbumDateSectionHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1A26CD22739194300433E9F /* AlbumDateSectionHeaderView.swift */; }; F1E5DE7D26A57F0B004B9EDE /* DetailListViewControllerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1E5DE7C26A57F0B004B9EDE /* DetailListViewControllerProtocol.swift */; }; F1E5DE8026A58346004B9EDE /* MomentInfoSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1E5DE7F26A58346004B9EDE /* MomentInfoSection.swift */; }; F1E5DE8226A58386004B9EDE /* MomentInfoSectionCreater.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1E5DE8126A58386004B9EDE /* MomentInfoSectionCreater.swift */; }; @@ -80,6 +83,9 @@ 3590F1F51EC1A79400F32E06 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/NohanaImagePicker.strings; sourceTree = ""; }; F181094F26A5361A001C2BDE /* MomentDetailListViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MomentDetailListViewController.swift; sourceTree = ""; }; F1A26CCC2738DE6A00433E9F /* AssetListSelectableDateSection.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = AssetListSelectableDateSection.storyboard; sourceTree = ""; }; + F1A26CCE2738E7E400433E9F /* AssetListSelectableDateSectionController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetListSelectableDateSectionController.swift; sourceTree = ""; }; + F1A26CD02738E88700433E9F /* AlbumDateSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumDateSection.swift; sourceTree = ""; }; + F1A26CD22739194300433E9F /* AlbumDateSectionHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumDateSectionHeaderView.swift; sourceTree = ""; }; F1E5DE7C26A57F0B004B9EDE /* DetailListViewControllerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailListViewControllerProtocol.swift; sourceTree = ""; }; F1E5DE7F26A58346004B9EDE /* MomentInfoSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MomentInfoSection.swift; sourceTree = ""; }; F1E5DE8126A58386004B9EDE /* MomentInfoSectionCreater.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MomentInfoSectionCreater.swift; sourceTree = ""; }; @@ -155,6 +161,7 @@ children = ( F1E5DE7F26A58346004B9EDE /* MomentInfoSection.swift */, F1E5DE8126A58386004B9EDE /* MomentInfoSectionCreater.swift */, + F1A26CD02738E88700433E9F /* AlbumDateSection.swift */, ); name = Models; sourceTree = ""; @@ -182,6 +189,7 @@ F25C69871CA23A0A005935D6 /* MomentCell.swift */, F2FE1F761C901D9400FDBE7B /* MomentSectionHeaderView.swift */, F25C69911CA28728005935D6 /* AlbumListEmptyIndicator.swift */, + F1A26CD22739194300433E9F /* AlbumDateSectionHeaderView.swift */, ); name = Views; sourceTree = ""; @@ -275,6 +283,7 @@ F2DF3B2A1C6CC4DB00C1C0E4 /* AssetDetailListViewController.swift */, F181094F26A5361A001C2BDE /* MomentDetailListViewController.swift */, F1E5DE7C26A57F0B004B9EDE /* DetailListViewControllerProtocol.swift */, + F1A26CCE2738E7E400433E9F /* AssetListSelectableDateSectionController.swift */, ); name = ViewControllers; sourceTree = ""; @@ -420,6 +429,7 @@ F25C10C21C8ED9BF007453C3 /* MomentViewController.swift in Sources */, F25C69881CA23A0A005935D6 /* MomentCell.swift in Sources */, F2FE1F781C901D9400FDBE7B /* MomentSectionHeaderView.swift in Sources */, + F1A26CD12738E88700433E9F /* AlbumDateSection.swift in Sources */, F23554281C69D5DB00796DCA /* NohanaImagePickerController.swift in Sources */, F1E5DE8026A58346004B9EDE /* MomentInfoSection.swift in Sources */, F181095026A5361A001C2BDE /* MomentDetailListViewController.swift in Sources */, @@ -428,11 +438,13 @@ F2DF3B2D1C6D780100C1C0E4 /* AssetDetailCell.swift in Sources */, F25C69901CA27311005935D6 /* EmptyIndicatable.swift in Sources */, F2DA29771C7749D600B0A8E3 /* NotificationInfo.swift in Sources */, + F1A26CCF2738E7E400433E9F /* AssetListSelectableDateSectionController.swift in Sources */, F1E5DE7D26A57F0B004B9EDE /* DetailListViewControllerProtocol.swift in Sources */, F218D7DE1C6C3A5B001FCED1 /* AlbumCell.swift in Sources */, F26775E11C7046C7002E786C /* ExpandingAnimationController.swift in Sources */, F28F4AC51C6C59A500B7D725 /* PhotoKitAsset.swift in Sources */, F2DF3B151C6C76E500C1C0E4 /* AssetListViewController.swift in Sources */, + F1A26CD32739194300433E9F /* AlbumDateSectionHeaderView.swift in Sources */, F26775E51C70574F002E786C /* AnimatableNavigationController.swift in Sources */, F2DF3B2B1C6CC4DB00C1C0E4 /* AssetDetailListViewController.swift in Sources */, F218D7D61C6B3D22001FCED1 /* PhotoKitAlbumList.swift in Sources */, diff --git a/NohanaImagePicker/AlbumDateSection.swift b/NohanaImagePicker/AlbumDateSection.swift new file mode 100644 index 0000000..9b15dcd --- /dev/null +++ b/NohanaImagePicker/AlbumDateSection.swift @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2021 nohana, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Photos + +struct AlbumDateSection { + let creationDate: Date + let assetResult: [PHAsset] +} diff --git a/NohanaImagePicker/AlbumDateSectionHeaderView.swift b/NohanaImagePicker/AlbumDateSectionHeaderView.swift new file mode 100644 index 0000000..a43f45f --- /dev/null +++ b/NohanaImagePicker/AlbumDateSectionHeaderView.swift @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2021 nohana, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import UIKit + +class AlbumDateSectionHeaderView: UICollectionReusableView { + @IBOutlet weak var dateLabel: UILabel! +} diff --git a/NohanaImagePicker/AlbumListViewController.swift b/NohanaImagePicker/AlbumListViewController.swift index 930f003..5488470 100644 --- a/NohanaImagePicker/AlbumListViewController.swift +++ b/NohanaImagePicker/AlbumListViewController.swift @@ -195,8 +195,9 @@ class AlbumListViewController: UITableViewController, EmptyIndicatable, Activity assetListViewController.photoKitAssetList = photoKitAlbumList[tableView.indexPathForSelectedRow!.row] assetListViewController.nohanaImagePickerController = nohanaImagePickerController case "toAssetListViewSelectableDateSectionController": - // TODO - print("show selectable view") + let assetListSelectableDateSectionController = segue.destination as! AssetListSelectableDateSectionController + assetListSelectableDateSectionController.photoKitAssetList = photoKitAlbumList[tableView.indexPathForSelectedRow!.row] + assetListSelectableDateSectionController.nohanaImagePickerController = nohanaImagePickerController default: fatalError("unexpected segue identifer") } diff --git a/NohanaImagePicker/AssetListSelectableDateSection.storyboard b/NohanaImagePicker/AssetListSelectableDateSection.storyboard index bc0e3e3..9cabb61 100644 --- a/NohanaImagePicker/AssetListSelectableDateSection.storyboard +++ b/NohanaImagePicker/AssetListSelectableDateSection.storyboard @@ -1,35 +1,126 @@ - + - - - + + - - - - - - - + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - diff --git a/NohanaImagePicker/AssetListSelectableDateSectionController.swift b/NohanaImagePicker/AssetListSelectableDateSectionController.swift new file mode 100644 index 0000000..6c0360d --- /dev/null +++ b/NohanaImagePicker/AssetListSelectableDateSectionController.swift @@ -0,0 +1,229 @@ +/* + * Copyright (C) 2021 nohana, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Foundation +import Photos + +class AssetListSelectableDateSectionController: UICollectionViewController, UICollectionViewDelegateFlowLayout, ActivityIndicatable { + + weak var nohanaImagePickerController: NohanaImagePickerController? + var photoKitAssetList: PhotoKitAssetList! + var dateSectionList: [AlbumDateSection] = [] + var isFirstAppearance = true + + var cellSize: CGSize { + guard let nohanaImagePickerController = nohanaImagePickerController else { + return CGSize.zero + } + var numberOfColumns = nohanaImagePickerController.numberOfColumnsInLandscape + if UIApplication.shared.statusBarOrientation.isPortrait { + numberOfColumns = nohanaImagePickerController.numberOfColumnsInPortrait + } + let cellMargin: CGFloat = 2 + let cellWidth = (view.frame.width - cellMargin * (CGFloat(numberOfColumns) - 1)) / CGFloat(numberOfColumns) + return CGSize(width: cellWidth, height: cellWidth) + } + + override func viewDidLoad() { + super.viewDidLoad() + view.backgroundColor = nohanaImagePickerController?.config.color.background ?? .white + updateTitle() + setUpToolbarItems() + addPickPhotoKitAssetNotificationObservers() + setUpActivityIndicator() + DispatchQueue.main.async { [weak self] in + guard let self = self else { return } + // TODO: DI + self.dateSectionList = { [weak self] in + guard let self = self else { return [] } + var albumDateSectionList = [AlbumDateSection]() + let options = PHFetchOptions() + options.predicate = NSPredicate(format: "mediaType == %ld", PHAssetMediaType.image.rawValue) + options.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: true)] + let fetchAssetlist = PHAsset.fetchAssets(in: self.photoKitAssetList.assetList, options: options) + let allAssets = fetchAssetlist.objects(at: IndexSet(0.. 0 { + if assetsByDate[assetsByDateIndex - 1].0 == calender.dateComponents([.day, .year, .month], from: (asset.creationDate)!) { + assetsByDate[assetsByDateIndex - 1].1.append(asset) + } else { + let value = (calender.dateComponents([.day, .year, .month], from: (asset.creationDate)!), [asset]) + assetsByDate.append(value) + assetsByDateIndex += 1 + } + } else if assetsByDate.count == assetsByDateIndex { + let value = (calender.dateComponents([.day, .year, .month], from: (asset.creationDate)!), [asset]) + assetsByDate.append(value) + assetsByDateIndex += 1 + } + } + albumDateSectionList = assetsByDate.map { AlbumDateSection(creationDate: calender.date(from: $0.0) ?? Date(timeIntervalSince1970: 0), assetResult: $0.1) } + + return albumDateSectionList + }() + self.isLoading = false + self.collectionView?.reloadData() + self.isFirstAppearance = true + self.scrollCollectionViewToInitialPosition() + } + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + if let nohanaImagePickerController = nohanaImagePickerController { + setToolbarTitle(nohanaImagePickerController) + } + collectionView?.reloadData() + scrollCollectionViewToInitialPosition() + } + + func updateTitle() { + title = photoKitAssetList.title + } + + func scrollCollectionView(to indexPath: IndexPath) { + let count: Int? = dateSectionList.count + guard count != nil && count! > 0 else { + return + } + DispatchQueue.main.async { + self.collectionView?.scrollToItem(at: indexPath, at: .bottom, animated: false) + } + } + + func scrollCollectionViewToInitialPosition() { + guard isFirstAppearance else { + return + } + let lastSection = dateSectionList.count - 1 + guard lastSection >= 0 else { + return + } + let indexPath = IndexPath(item: dateSectionList[lastSection].assetResult.count - 1, section: lastSection) + scrollCollectionView(to: indexPath) + isFirstAppearance = false + } + + // MARK: - UICollectionViewDataSource + + override func numberOfSections(in collectionView: UICollectionView) -> Int { + if let activityIndicator = activityIndicator { + updateVisibilityOfActivityIndicator(activityIndicator) + } + + return dateSectionList.count + } + + override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return dateSectionList[section].assetResult.count + } + + // MARK: - UICollectionViewDelegate + + override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "AssetCell", for: indexPath) as? AssetCell, + let nohanaImagePickerController = nohanaImagePickerController else { + fatalError("failed to dequeueReusableCellWithIdentifier(\"AssetCell\")") + } + + let asset = PhotoKitAsset(asset: dateSectionList[indexPath.section].assetResult[indexPath.row]) + cell.tag = indexPath.item + cell.update(asset: asset, nohanaImagePickerController: nohanaImagePickerController) + + let imageSize = CGSize( + width: cellSize.width * UIScreen.main.scale, + height: cellSize.height * UIScreen.main.scale + ) + asset.image(targetSize: imageSize) { (imageData) -> Void in + DispatchQueue.main.async(execute: { () -> Void in + if let imageData = imageData { + if cell.tag == indexPath.item { + cell.imageView.image = imageData.image + } + } + }) + } + return (nohanaImagePickerController.delegate?.nohanaImagePicker?(nohanaImagePickerController, assetListViewController: self, cell: cell, indexPath: indexPath, photoKitAsset: asset.originalAsset)) ?? cell + } + + override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { + switch kind { + case UICollectionView.elementKindSectionHeader: + let album = dateSectionList[indexPath.section] + guard let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "AlbumDateSectionHeader", for: indexPath) as? AlbumDateSectionHeaderView else { + fatalError("failed to create AlbumDateSectionHeader") + } + let formatter = DateFormatter() + formatter.dateStyle = .long + formatter.timeStyle = DateFormatter.Style.none + header.dateLabel.text = formatter.string(from: album.creationDate) + return header + default: + fatalError("failed to create AlbumDateSectionHeader") + } + } + + // MARK: - UICollectionViewDelegateFlowLayout + + func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { + return cellSize + } + + // MARK: - ActivityIndicatable + + var activityIndicator: UIActivityIndicatorView? + var isLoading = true + + func setUpActivityIndicator() { + activityIndicator = UIActivityIndicatorView(style: .gray) + let screenRect = Size.screenRectWithoutAppBar(self) + activityIndicator?.center = CGPoint(x: screenRect.size.width / 2, y: screenRect.size.height / 2) + activityIndicator?.startAnimating() + } + + func isProgressing() -> Bool { + return isLoading + } + + // MARK: - UICollectionViewDelegate + + override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + if let nohanaImagePickerController = nohanaImagePickerController { + nohanaImagePickerController.delegate?.nohanaImagePicker?(nohanaImagePickerController, didSelectPhotoKitAsset: dateSectionList[indexPath.section].assetResult[indexPath.row]) + } + } + + // MARK: - Storyboard + + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + guard let selectedIndexPath = collectionView?.indexPathsForSelectedItems?.first else { + return + } + // TODO show detail views + } + + // MARK: - IBAction + + @IBAction func didPushDone(_ sender: AnyObject) { + if let nohanaImagePickerController = nohanaImagePickerController { + let pickedPhotoKitAssets = nohanaImagePickerController.pickedAssetList.map { ($0 as! PhotoKitAsset).originalAsset } + nohanaImagePickerController.delegate?.nohanaImagePicker(nohanaImagePickerController, didFinishPickingPhotoKitAssets: pickedPhotoKitAssets) + } + } +} From defb1b07815c136f180d6da90ae66c40ff05d480 Mon Sep 17 00:00:00 2001 From: "naoto.suzuki" Date: Tue, 9 Nov 2021 10:38:49 +0900 Subject: [PATCH 03/26] Renamed and Added pick buttton. --- NohanaImagePicker.xcodeproj/project.pbxproj | 16 ++++----- .../AlbumDateSectionHeaderView.swift | 21 ----------- ...teSection.swift => AssetDateSection.swift} | 2 +- .../AssetDateSectionHeaderView.swift | 36 +++++++++++++++++++ .../AssetListSelectableDateSection.storyboard | 24 ++++++++++--- ...tListSelectableDateSectionController.swift | 14 ++++---- 6 files changed, 72 insertions(+), 41 deletions(-) delete mode 100644 NohanaImagePicker/AlbumDateSectionHeaderView.swift rename NohanaImagePicker/{AlbumDateSection.swift => AssetDateSection.swift} (96%) create mode 100644 NohanaImagePicker/AssetDateSectionHeaderView.swift diff --git a/NohanaImagePicker.xcodeproj/project.pbxproj b/NohanaImagePicker.xcodeproj/project.pbxproj index 498d644..89b8cae 100644 --- a/NohanaImagePicker.xcodeproj/project.pbxproj +++ b/NohanaImagePicker.xcodeproj/project.pbxproj @@ -11,8 +11,8 @@ F181095026A5361A001C2BDE /* MomentDetailListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F181094F26A5361A001C2BDE /* MomentDetailListViewController.swift */; }; F1A26CCD2738DE6A00433E9F /* AssetListSelectableDateSection.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F1A26CCC2738DE6A00433E9F /* AssetListSelectableDateSection.storyboard */; }; F1A26CCF2738E7E400433E9F /* AssetListSelectableDateSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1A26CCE2738E7E400433E9F /* AssetListSelectableDateSectionController.swift */; }; - F1A26CD12738E88700433E9F /* AlbumDateSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1A26CD02738E88700433E9F /* AlbumDateSection.swift */; }; - F1A26CD32739194300433E9F /* AlbumDateSectionHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1A26CD22739194300433E9F /* AlbumDateSectionHeaderView.swift */; }; + F1A26CD12738E88700433E9F /* AssetDateSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1A26CD02738E88700433E9F /* AssetDateSection.swift */; }; + F1A26CD32739194300433E9F /* AssetDateSectionHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1A26CD22739194300433E9F /* AssetDateSectionHeaderView.swift */; }; F1E5DE7D26A57F0B004B9EDE /* DetailListViewControllerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1E5DE7C26A57F0B004B9EDE /* DetailListViewControllerProtocol.swift */; }; F1E5DE8026A58346004B9EDE /* MomentInfoSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1E5DE7F26A58346004B9EDE /* MomentInfoSection.swift */; }; F1E5DE8226A58386004B9EDE /* MomentInfoSectionCreater.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1E5DE8126A58386004B9EDE /* MomentInfoSectionCreater.swift */; }; @@ -84,8 +84,8 @@ F181094F26A5361A001C2BDE /* MomentDetailListViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MomentDetailListViewController.swift; sourceTree = ""; }; F1A26CCC2738DE6A00433E9F /* AssetListSelectableDateSection.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = AssetListSelectableDateSection.storyboard; sourceTree = ""; }; F1A26CCE2738E7E400433E9F /* AssetListSelectableDateSectionController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetListSelectableDateSectionController.swift; sourceTree = ""; }; - F1A26CD02738E88700433E9F /* AlbumDateSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumDateSection.swift; sourceTree = ""; }; - F1A26CD22739194300433E9F /* AlbumDateSectionHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumDateSectionHeaderView.swift; sourceTree = ""; }; + F1A26CD02738E88700433E9F /* AssetDateSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetDateSection.swift; sourceTree = ""; }; + F1A26CD22739194300433E9F /* AssetDateSectionHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetDateSectionHeaderView.swift; sourceTree = ""; }; F1E5DE7C26A57F0B004B9EDE /* DetailListViewControllerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailListViewControllerProtocol.swift; sourceTree = ""; }; F1E5DE7F26A58346004B9EDE /* MomentInfoSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MomentInfoSection.swift; sourceTree = ""; }; F1E5DE8126A58386004B9EDE /* MomentInfoSectionCreater.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MomentInfoSectionCreater.swift; sourceTree = ""; }; @@ -161,7 +161,7 @@ children = ( F1E5DE7F26A58346004B9EDE /* MomentInfoSection.swift */, F1E5DE8126A58386004B9EDE /* MomentInfoSectionCreater.swift */, - F1A26CD02738E88700433E9F /* AlbumDateSection.swift */, + F1A26CD02738E88700433E9F /* AssetDateSection.swift */, ); name = Models; sourceTree = ""; @@ -189,7 +189,7 @@ F25C69871CA23A0A005935D6 /* MomentCell.swift */, F2FE1F761C901D9400FDBE7B /* MomentSectionHeaderView.swift */, F25C69911CA28728005935D6 /* AlbumListEmptyIndicator.swift */, - F1A26CD22739194300433E9F /* AlbumDateSectionHeaderView.swift */, + F1A26CD22739194300433E9F /* AssetDateSectionHeaderView.swift */, ); name = Views; sourceTree = ""; @@ -429,7 +429,7 @@ F25C10C21C8ED9BF007453C3 /* MomentViewController.swift in Sources */, F25C69881CA23A0A005935D6 /* MomentCell.swift in Sources */, F2FE1F781C901D9400FDBE7B /* MomentSectionHeaderView.swift in Sources */, - F1A26CD12738E88700433E9F /* AlbumDateSection.swift in Sources */, + F1A26CD12738E88700433E9F /* AssetDateSection.swift in Sources */, F23554281C69D5DB00796DCA /* NohanaImagePickerController.swift in Sources */, F1E5DE8026A58346004B9EDE /* MomentInfoSection.swift in Sources */, F181095026A5361A001C2BDE /* MomentDetailListViewController.swift in Sources */, @@ -444,7 +444,7 @@ F26775E11C7046C7002E786C /* ExpandingAnimationController.swift in Sources */, F28F4AC51C6C59A500B7D725 /* PhotoKitAsset.swift in Sources */, F2DF3B151C6C76E500C1C0E4 /* AssetListViewController.swift in Sources */, - F1A26CD32739194300433E9F /* AlbumDateSectionHeaderView.swift in Sources */, + F1A26CD32739194300433E9F /* AssetDateSectionHeaderView.swift in Sources */, F26775E51C70574F002E786C /* AnimatableNavigationController.swift in Sources */, F2DF3B2B1C6CC4DB00C1C0E4 /* AssetDetailListViewController.swift in Sources */, F218D7D61C6B3D22001FCED1 /* PhotoKitAlbumList.swift in Sources */, diff --git a/NohanaImagePicker/AlbumDateSectionHeaderView.swift b/NohanaImagePicker/AlbumDateSectionHeaderView.swift deleted file mode 100644 index a43f45f..0000000 --- a/NohanaImagePicker/AlbumDateSectionHeaderView.swift +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2021 nohana, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import UIKit - -class AlbumDateSectionHeaderView: UICollectionReusableView { - @IBOutlet weak var dateLabel: UILabel! -} diff --git a/NohanaImagePicker/AlbumDateSection.swift b/NohanaImagePicker/AssetDateSection.swift similarity index 96% rename from NohanaImagePicker/AlbumDateSection.swift rename to NohanaImagePicker/AssetDateSection.swift index 9b15dcd..bc582bf 100644 --- a/NohanaImagePicker/AlbumDateSection.swift +++ b/NohanaImagePicker/AssetDateSection.swift @@ -16,7 +16,7 @@ import Photos -struct AlbumDateSection { +struct AssetDateSection { let creationDate: Date let assetResult: [PHAsset] } diff --git a/NohanaImagePicker/AssetDateSectionHeaderView.swift b/NohanaImagePicker/AssetDateSectionHeaderView.swift new file mode 100644 index 0000000..d29c62f --- /dev/null +++ b/NohanaImagePicker/AssetDateSectionHeaderView.swift @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2021 nohana, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import UIKit + +class AssetDateSectionHeaderView: UICollectionReusableView { + @IBOutlet weak var dateLabel: UILabel! + @IBOutlet weak var pickButton: UIButton! + + @IBAction func didPushPickButton(_ sender: UIButton) { + // TODO data selection + sender.isSelected = !sender.isSelected + } + + func update(nohanaImagePickerController: NohanaImagePickerController) { + if pickButton.image(for: UIControl.State()) == nil, pickButton.image(for: .selected) == nil { + let droppedImage: UIImage? = nohanaImagePickerController.config.image.droppedSmall ?? UIImage(named: "btn_select_l", in: nohanaImagePickerController.assetBundle, compatibleWith: nil) + let pickedImage: UIImage? = nohanaImagePickerController.config.image.pickedSmall ?? UIImage(named: "btn_selected_l", in: nohanaImagePickerController.assetBundle, compatibleWith: nil) + pickButton.setImage(droppedImage, for: UIControl.State()) + pickButton.setImage(pickedImage, for: .selected) + } + } +} diff --git a/NohanaImagePicker/AssetListSelectableDateSection.storyboard b/NohanaImagePicker/AssetListSelectableDateSection.storyboard index 9cabb61..f7e1314 100644 --- a/NohanaImagePicker/AssetListSelectableDateSection.storyboard +++ b/NohanaImagePicker/AssetListSelectableDateSection.storyboard @@ -17,13 +17,13 @@ - + - + @@ -68,12 +68,12 @@ - - + + + + + + @@ -101,6 +114,7 @@ + diff --git a/NohanaImagePicker/AssetListSelectableDateSectionController.swift b/NohanaImagePicker/AssetListSelectableDateSectionController.swift index 6c0360d..9c7ce38 100644 --- a/NohanaImagePicker/AssetListSelectableDateSectionController.swift +++ b/NohanaImagePicker/AssetListSelectableDateSectionController.swift @@ -21,7 +21,7 @@ class AssetListSelectableDateSectionController: UICollectionViewController, UICo weak var nohanaImagePickerController: NohanaImagePickerController? var photoKitAssetList: PhotoKitAssetList! - var dateSectionList: [AlbumDateSection] = [] + var dateSectionList: [AssetDateSection] = [] var isFirstAppearance = true var cellSize: CGSize { @@ -49,7 +49,7 @@ class AssetListSelectableDateSectionController: UICollectionViewController, UICo // TODO: DI self.dateSectionList = { [weak self] in guard let self = self else { return [] } - var albumDateSectionList = [AlbumDateSection]() + var albumDateSectionList = [AssetDateSection]() let options = PHFetchOptions() options.predicate = NSPredicate(format: "mediaType == %ld", PHAssetMediaType.image.rawValue) options.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: true)] @@ -73,7 +73,7 @@ class AssetListSelectableDateSectionController: UICollectionViewController, UICo assetsByDateIndex += 1 } } - albumDateSectionList = assetsByDate.map { AlbumDateSection(creationDate: calender.date(from: $0.0) ?? Date(timeIntervalSince1970: 0), assetResult: $0.1) } + albumDateSectionList = assetsByDate.map { AssetDateSection(creationDate: calender.date(from: $0.0) ?? Date(timeIntervalSince1970: 0), assetResult: $0.1) } return albumDateSectionList }() @@ -166,16 +166,18 @@ class AssetListSelectableDateSectionController: UICollectionViewController, UICo switch kind { case UICollectionView.elementKindSectionHeader: let album = dateSectionList[indexPath.section] - guard let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "AlbumDateSectionHeader", for: indexPath) as? AlbumDateSectionHeaderView else { - fatalError("failed to create AlbumDateSectionHeader") + guard let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "AssetDateSectionHeader", for: indexPath) as? AssetDateSectionHeaderView, + let nohanaImagePickerController = nohanaImagePickerController else { + fatalError("failed to create AssetDateSectionHeader") } let formatter = DateFormatter() formatter.dateStyle = .long formatter.timeStyle = DateFormatter.Style.none header.dateLabel.text = formatter.string(from: album.creationDate) + header.update(nohanaImagePickerController: nohanaImagePickerController) return header default: - fatalError("failed to create AlbumDateSectionHeader") + fatalError("failed to create AssetDateSectionHeader") } } From 91ef2fc05df377c9b8c8f20cab5efdb837f209ae Mon Sep 17 00:00:00 2001 From: "naoto.suzuki" Date: Tue, 9 Nov 2021 11:35:42 +0900 Subject: [PATCH 04/26] Added select section cells. --- .../AssetDateSectionHeaderView.swift | 21 ++++++++++++++----- ...tListSelectableDateSectionController.swift | 21 ++++++++++++++++++- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/NohanaImagePicker/AssetDateSectionHeaderView.swift b/NohanaImagePicker/AssetDateSectionHeaderView.swift index d29c62f..cee4d90 100644 --- a/NohanaImagePicker/AssetDateSectionHeaderView.swift +++ b/NohanaImagePicker/AssetDateSectionHeaderView.swift @@ -16,21 +16,32 @@ import UIKit +protocol AssetDateSectionHeaderViewDelegate: AnyObject { + func didPushPickButton(isSelected: Bool, indexPath: IndexPath) +} + class AssetDateSectionHeaderView: UICollectionReusableView { @IBOutlet weak var dateLabel: UILabel! @IBOutlet weak var pickButton: UIButton! - + var indexPath: IndexPath? + weak var delegate: AssetDateSectionHeaderViewDelegate? + @IBAction func didPushPickButton(_ sender: UIButton) { - // TODO data selection - sender.isSelected = !sender.isSelected + if let indexPath = indexPath { + delegate?.didPushPickButton(isSelected: sender.isSelected, indexPath: indexPath) + sender.isSelected = !sender.isSelected + } } - - func update(nohanaImagePickerController: NohanaImagePickerController) { + + func update(assets: [Asset], indexPath: IndexPath, nohanaImagePickerController: NohanaImagePickerController) { + self.indexPath = indexPath if pickButton.image(for: UIControl.State()) == nil, pickButton.image(for: .selected) == nil { let droppedImage: UIImage? = nohanaImagePickerController.config.image.droppedSmall ?? UIImage(named: "btn_select_l", in: nohanaImagePickerController.assetBundle, compatibleWith: nil) let pickedImage: UIImage? = nohanaImagePickerController.config.image.pickedSmall ?? UIImage(named: "btn_selected_l", in: nohanaImagePickerController.assetBundle, compatibleWith: nil) pickButton.setImage(droppedImage, for: UIControl.State()) pickButton.setImage(pickedImage, for: .selected) } + let isAllSelected = !assets.map { nohanaImagePickerController.pickedAssetList.isPicked($0) }.contains(where: {$0 == false}) + pickButton.isSelected = isAllSelected } } diff --git a/NohanaImagePicker/AssetListSelectableDateSectionController.swift b/NohanaImagePicker/AssetListSelectableDateSectionController.swift index 9c7ce38..ebc2d18 100644 --- a/NohanaImagePicker/AssetListSelectableDateSectionController.swift +++ b/NohanaImagePicker/AssetListSelectableDateSectionController.swift @@ -174,7 +174,9 @@ class AssetListSelectableDateSectionController: UICollectionViewController, UICo formatter.dateStyle = .long formatter.timeStyle = DateFormatter.Style.none header.dateLabel.text = formatter.string(from: album.creationDate) - header.update(nohanaImagePickerController: nohanaImagePickerController) + header.delegate = self + let assets = dateSectionList[indexPath.section].assetResult.map { PhotoKitAsset(asset: $0) } + header.update(assets: assets, indexPath: indexPath, nohanaImagePickerController: nohanaImagePickerController) return header default: fatalError("failed to create AssetDateSectionHeader") @@ -229,3 +231,20 @@ class AssetListSelectableDateSectionController: UICollectionViewController, UICo } } } + +// MARK: - AssetDateSectionHeaderViewDelegate +extension AssetListSelectableDateSectionController: AssetDateSectionHeaderViewDelegate { + func didPushPickButton(isSelected: Bool, indexPath: IndexPath) { + let assets = dateSectionList[indexPath.section].assetResult.map { PhotoKitAsset(asset: $0) } + for asset in assets { + if isSelected { + _ = nohanaImagePickerController?.pickedAssetList.drop(asset: asset) + } else { + if nohanaImagePickerController?.canPickAsset(asset) ?? false { + _ = nohanaImagePickerController?.pickedAssetList.pick(asset: asset) + } + } + } + collectionView.reloadItems(at: collectionView.indexPathsForVisibleItems) + } +} From 8dbf7b967af3db2a39555060ff660c09a6ec6092 Mon Sep 17 00:00:00 2001 From: "naoto.suzuki" Date: Tue, 9 Nov 2021 14:48:41 +0900 Subject: [PATCH 05/26] Added section state from cell. --- NohanaImagePicker/AssetCell.swift | 6 ++++++ ...AssetListSelectableDateSectionController.swift | 15 +++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/NohanaImagePicker/AssetCell.swift b/NohanaImagePicker/AssetCell.swift index ca1a299..0410811 100644 --- a/NohanaImagePicker/AssetCell.swift +++ b/NohanaImagePicker/AssetCell.swift @@ -15,12 +15,17 @@ */ import UIKit +protocol AssetCellDelegate: AnyObject { + func didPushPickButton(cell: AssetCell) +} + class AssetCell: UICollectionViewCell { @IBOutlet weak var imageView: UIImageView! @IBOutlet weak var pickButton: UIButton! @IBOutlet weak var overlayView: UIView! + weak var delegate: AssetCellDelegate? weak var nohanaImagePickerController: NohanaImagePickerController? var asset: Asset? @@ -49,6 +54,7 @@ class AssetCell: UICollectionViewCell { } } self.overlayView.isHidden = !pickButton.isSelected + delegate?.didPushPickButton(cell: self) } func update(asset: Asset, nohanaImagePickerController: NohanaImagePickerController) { diff --git a/NohanaImagePicker/AssetListSelectableDateSectionController.swift b/NohanaImagePicker/AssetListSelectableDateSectionController.swift index ebc2d18..7884997 100644 --- a/NohanaImagePicker/AssetListSelectableDateSectionController.swift +++ b/NohanaImagePicker/AssetListSelectableDateSectionController.swift @@ -144,6 +144,7 @@ class AssetListSelectableDateSectionController: UICollectionViewController, UICo let asset = PhotoKitAsset(asset: dateSectionList[indexPath.section].assetResult[indexPath.row]) cell.tag = indexPath.item + cell.delegate = self cell.update(asset: asset, nohanaImagePickerController: nohanaImagePickerController) let imageSize = CGSize( @@ -248,3 +249,17 @@ extension AssetListSelectableDateSectionController: AssetDateSectionHeaderViewDe collectionView.reloadItems(at: collectionView.indexPathsForVisibleItems) } } + +// MARK: - AssetCellDelegate +extension AssetListSelectableDateSectionController: AssetCellDelegate { + func didPushPickButton(cell: AssetCell) { + if let indexPath = collectionView.indexPath(for: cell) { + UIView.animate(withDuration: 0) { [weak self] in + self?.collectionView.performBatchUpdates({ [weak self] in + let indexSet = IndexSet(integer: indexPath.section) + self?.collectionView.reloadSections(indexSet) + }, completion: nil) + } + } + } +} From 91245727f4dffe1113abdfbf2a69ac7ffc79664f Mon Sep 17 00:00:00 2001 From: "naoto.suzuki" Date: Tue, 9 Nov 2021 16:50:47 +0900 Subject: [PATCH 06/26] Modified select section logic. --- .../AssetDateSectionHeaderView.swift | 31 +++++++++++++++---- ...tListSelectableDateSectionController.swift | 12 +------ 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/NohanaImagePicker/AssetDateSectionHeaderView.swift b/NohanaImagePicker/AssetDateSectionHeaderView.swift index cee4d90..360f2b0 100644 --- a/NohanaImagePicker/AssetDateSectionHeaderView.swift +++ b/NohanaImagePicker/AssetDateSectionHeaderView.swift @@ -17,24 +17,43 @@ import UIKit protocol AssetDateSectionHeaderViewDelegate: AnyObject { - func didPushPickButton(isSelected: Bool, indexPath: IndexPath) + func didPushPickButton() } class AssetDateSectionHeaderView: UICollectionReusableView { @IBOutlet weak var dateLabel: UILabel! @IBOutlet weak var pickButton: UIButton! - var indexPath: IndexPath? + var assets = [Asset]() + weak var nohanaImagePickerController: NohanaImagePickerController? weak var delegate: AssetDateSectionHeaderViewDelegate? @IBAction func didPushPickButton(_ sender: UIButton) { - if let indexPath = indexPath { - delegate?.didPushPickButton(isSelected: sender.isSelected, indexPath: indexPath) - sender.isSelected = !sender.isSelected + let firstButtonState = sender.isSelected + var isNotPickedAsset = false + for asset in assets { + if firstButtonState { + _ = nohanaImagePickerController?.pickedAssetList.drop(asset: asset) + sender.isSelected = false + } else { + guard nohanaImagePickerController?.canPickAsset(asset) ?? false, + !(nohanaImagePickerController?.pickedAssetList.isPicked(asset) ?? true) + else { continue } + if nohanaImagePickerController?.pickedAssetList.pick(asset: asset) ?? false { + sender.isSelected = true + } else { + isNotPickedAsset = true + } + } } + if isNotPickedAsset { + sender.isSelected = false + } + delegate?.didPushPickButton() } func update(assets: [Asset], indexPath: IndexPath, nohanaImagePickerController: NohanaImagePickerController) { - self.indexPath = indexPath + self.assets = assets + self.nohanaImagePickerController = nohanaImagePickerController if pickButton.image(for: UIControl.State()) == nil, pickButton.image(for: .selected) == nil { let droppedImage: UIImage? = nohanaImagePickerController.config.image.droppedSmall ?? UIImage(named: "btn_select_l", in: nohanaImagePickerController.assetBundle, compatibleWith: nil) let pickedImage: UIImage? = nohanaImagePickerController.config.image.pickedSmall ?? UIImage(named: "btn_selected_l", in: nohanaImagePickerController.assetBundle, compatibleWith: nil) diff --git a/NohanaImagePicker/AssetListSelectableDateSectionController.swift b/NohanaImagePicker/AssetListSelectableDateSectionController.swift index 7884997..5e189f8 100644 --- a/NohanaImagePicker/AssetListSelectableDateSectionController.swift +++ b/NohanaImagePicker/AssetListSelectableDateSectionController.swift @@ -235,17 +235,7 @@ class AssetListSelectableDateSectionController: UICollectionViewController, UICo // MARK: - AssetDateSectionHeaderViewDelegate extension AssetListSelectableDateSectionController: AssetDateSectionHeaderViewDelegate { - func didPushPickButton(isSelected: Bool, indexPath: IndexPath) { - let assets = dateSectionList[indexPath.section].assetResult.map { PhotoKitAsset(asset: $0) } - for asset in assets { - if isSelected { - _ = nohanaImagePickerController?.pickedAssetList.drop(asset: asset) - } else { - if nohanaImagePickerController?.canPickAsset(asset) ?? false { - _ = nohanaImagePickerController?.pickedAssetList.pick(asset: asset) - } - } - } + func didPushPickButton() { collectionView.reloadItems(at: collectionView.indexPathsForVisibleItems) } } From 366436fb15e0cc279067d6612038f88730b1d729 Mon Sep 17 00:00:00 2001 From: "naoto.suzuki" Date: Tue, 9 Nov 2021 17:13:57 +0900 Subject: [PATCH 07/26] Care asset date section if it can't pick photo only. --- NohanaImagePicker/AssetDateSectionHeaderView.swift | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/NohanaImagePicker/AssetDateSectionHeaderView.swift b/NohanaImagePicker/AssetDateSectionHeaderView.swift index 360f2b0..e1ef09c 100644 --- a/NohanaImagePicker/AssetDateSectionHeaderView.swift +++ b/NohanaImagePicker/AssetDateSectionHeaderView.swift @@ -60,7 +60,12 @@ class AssetDateSectionHeaderView: UICollectionReusableView { pickButton.setImage(droppedImage, for: UIControl.State()) pickButton.setImage(pickedImage, for: .selected) } - let isAllSelected = !assets.map { nohanaImagePickerController.pickedAssetList.isPicked($0) }.contains(where: {$0 == false}) + + let cantPickOnly = !assets.map { nohanaImagePickerController.canPickAsset($0) }.contains(where: {$0 == true}) + pickButton.isHidden = cantPickOnly + if cantPickOnly { return } + let canPickAssets = assets.compactMap { nohanaImagePickerController.canPickAsset($0) ? $0 : nil } + let isAllSelected = !canPickAssets.map { nohanaImagePickerController.pickedAssetList.isPicked($0) }.contains(where: {$0 == false}) pickButton.isSelected = isAllSelected } } From c4c946a70474f5aef39054dbb44637443e42925c Mon Sep 17 00:00:00 2001 From: "naoto.suzuki" Date: Tue, 9 Nov 2021 18:15:04 +0900 Subject: [PATCH 08/26] Fixed logic. --- NohanaImagePicker/AssetDateSectionHeaderView.swift | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/NohanaImagePicker/AssetDateSectionHeaderView.swift b/NohanaImagePicker/AssetDateSectionHeaderView.swift index e1ef09c..cd245f3 100644 --- a/NohanaImagePicker/AssetDateSectionHeaderView.swift +++ b/NohanaImagePicker/AssetDateSectionHeaderView.swift @@ -30,7 +30,9 @@ class AssetDateSectionHeaderView: UICollectionReusableView { @IBAction func didPushPickButton(_ sender: UIButton) { let firstButtonState = sender.isSelected var isNotPickedAsset = false - for asset in assets { + let maxSelectionCount = min(assets.count, nohanaImagePickerController?.maximumNumberOfSelection ?? assets.count) + for index in 0.. Date: Wed, 10 Nov 2021 11:34:30 +0900 Subject: [PATCH 09/26] Added detail screen. --- .../AssetListSelectableDateSection.storyboard | 87 +++++++++++++++++++ ...tListSelectableDateSectionController.swift | 17 +++- NohanaImagePicker/PhotoKitAssetList.swift | 1 + 3 files changed, 103 insertions(+), 2 deletions(-) diff --git a/NohanaImagePicker/AssetListSelectableDateSection.storyboard b/NohanaImagePicker/AssetListSelectableDateSection.storyboard index f7e1314..b7897df 100644 --- a/NohanaImagePicker/AssetListSelectableDateSection.storyboard +++ b/NohanaImagePicker/AssetListSelectableDateSection.storyboard @@ -65,6 +65,7 @@ + @@ -136,5 +137,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/NohanaImagePicker/AssetListSelectableDateSectionController.swift b/NohanaImagePicker/AssetListSelectableDateSectionController.swift index 5e189f8..4dae797 100644 --- a/NohanaImagePicker/AssetListSelectableDateSectionController.swift +++ b/NohanaImagePicker/AssetListSelectableDateSectionController.swift @@ -217,10 +217,23 @@ class AssetListSelectableDateSectionController: UICollectionViewController, UICo // MARK: - Storyboard override func prepare(for segue: UIStoryboardSegue, sender: Any?) { - guard let selectedIndexPath = collectionView?.indexPathsForSelectedItems?.first else { + guard let selectedIndexPath = collectionView?.indexPathsForSelectedItems?.first, + selectedIndexPath.section < dateSectionList.count else { return } - // TODO show detail views + var assetListDetailCurrentRow = 0 + for section in 0..<(selectedIndexPath.section + 1) { + if selectedIndexPath.section == section { + assetListDetailCurrentRow += selectedIndexPath.row + } else { + assetListDetailCurrentRow += dateSectionList[section].assetResult.count + } + } + + let assetListDetailViewController = segue.destination as! AssetDetailListViewController + assetListDetailViewController.photoKitAssetList = photoKitAssetList + assetListDetailViewController.nohanaImagePickerController = nohanaImagePickerController + assetListDetailViewController.currentIndexPath = IndexPath(item: assetListDetailCurrentRow, section: 0) } // MARK: - IBAction diff --git a/NohanaImagePicker/PhotoKitAssetList.swift b/NohanaImagePicker/PhotoKitAssetList.swift index d66f59b..c9633a2 100644 --- a/NohanaImagePicker/PhotoKitAssetList.swift +++ b/NohanaImagePicker/PhotoKitAssetList.swift @@ -45,6 +45,7 @@ open class PhotoKitAssetList: ItemList { switch mediaType { case .photo: options.predicate = NSPredicate(format: "mediaType == %ld", PHAssetMediaType.image.rawValue) + options.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: true)] default: fatalError("not supported .Video and .Any yet") } From a453e2205d38afb45ad6ce01782463f64129c1b1 Mon Sep 17 00:00:00 2001 From: "naoto.suzuki" Date: Wed, 10 Nov 2021 11:59:59 +0900 Subject: [PATCH 10/26] Modified section create. --- NohanaImagePicker.xcodeproj/project.pbxproj | 4 ++ .../AssetDateSectionCreater.swift | 46 +++++++++++++++++++ ...tListSelectableDateSectionController.swift | 32 +------------ NohanaImagePicker/PhotoKitAssetList.swift | 2 +- 4 files changed, 52 insertions(+), 32 deletions(-) create mode 100644 NohanaImagePicker/AssetDateSectionCreater.swift diff --git a/NohanaImagePicker.xcodeproj/project.pbxproj b/NohanaImagePicker.xcodeproj/project.pbxproj index 89b8cae..b91be97 100644 --- a/NohanaImagePicker.xcodeproj/project.pbxproj +++ b/NohanaImagePicker.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 3569CAA91EC1918E000C41C0 /* NohanaImagePicker.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3569CAA61EC1918E000C41C0 /* NohanaImagePicker.xcassets */; }; + F117F732273B6A2600E11BC7 /* AssetDateSectionCreater.swift in Sources */ = {isa = PBXBuildFile; fileRef = F117F731273B6A2600E11BC7 /* AssetDateSectionCreater.swift */; }; F181095026A5361A001C2BDE /* MomentDetailListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F181094F26A5361A001C2BDE /* MomentDetailListViewController.swift */; }; F1A26CCD2738DE6A00433E9F /* AssetListSelectableDateSection.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F1A26CCC2738DE6A00433E9F /* AssetListSelectableDateSection.storyboard */; }; F1A26CCF2738E7E400433E9F /* AssetListSelectableDateSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1A26CCE2738E7E400433E9F /* AssetListSelectableDateSectionController.swift */; }; @@ -81,6 +82,7 @@ 23D1CD93207CEB1200F8115E /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/NohanaImagePicker.strings; sourceTree = ""; }; 3569CAA61EC1918E000C41C0 /* NohanaImagePicker.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = NohanaImagePicker.xcassets; sourceTree = ""; }; 3590F1F51EC1A79400F32E06 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/NohanaImagePicker.strings; sourceTree = ""; }; + F117F731273B6A2600E11BC7 /* AssetDateSectionCreater.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetDateSectionCreater.swift; sourceTree = ""; }; F181094F26A5361A001C2BDE /* MomentDetailListViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MomentDetailListViewController.swift; sourceTree = ""; }; F1A26CCC2738DE6A00433E9F /* AssetListSelectableDateSection.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = AssetListSelectableDateSection.storyboard; sourceTree = ""; }; F1A26CCE2738E7E400433E9F /* AssetListSelectableDateSectionController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetListSelectableDateSectionController.swift; sourceTree = ""; }; @@ -162,6 +164,7 @@ F1E5DE7F26A58346004B9EDE /* MomentInfoSection.swift */, F1E5DE8126A58386004B9EDE /* MomentInfoSectionCreater.swift */, F1A26CD02738E88700433E9F /* AssetDateSection.swift */, + F117F731273B6A2600E11BC7 /* AssetDateSectionCreater.swift */, ); name = Models; sourceTree = ""; @@ -437,6 +440,7 @@ F2131F431C79615700797887 /* SwipeInteractionController.swift in Sources */, F2DF3B2D1C6D780100C1C0E4 /* AssetDetailCell.swift in Sources */, F25C69901CA27311005935D6 /* EmptyIndicatable.swift in Sources */, + F117F732273B6A2600E11BC7 /* AssetDateSectionCreater.swift in Sources */, F2DA29771C7749D600B0A8E3 /* NotificationInfo.swift in Sources */, F1A26CCF2738E7E400433E9F /* AssetListSelectableDateSectionController.swift in Sources */, F1E5DE7D26A57F0B004B9EDE /* DetailListViewControllerProtocol.swift in Sources */, diff --git a/NohanaImagePicker/AssetDateSectionCreater.swift b/NohanaImagePicker/AssetDateSectionCreater.swift new file mode 100644 index 0000000..2454ecc --- /dev/null +++ b/NohanaImagePicker/AssetDateSectionCreater.swift @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2021 nohana, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Photos + +final class AssetDateSectionCreater { + func createSections(assetList: PHAssetCollection, options: PHFetchOptions) -> [AssetDateSection] { + var albumDateSectionList = [AssetDateSection]() + let fetchAssetlist = PHAsset.fetchAssets(in: assetList, options: options) + let allAssets = fetchAssetlist.objects(at: IndexSet(0.. 0 { + if assetsByDate[assetsByDateIndex - 1].0 == calender.dateComponents([.day, .year, .month], from: (asset.creationDate)!) { + assetsByDate[assetsByDateIndex - 1].1.append(asset) + } else { + let value = (calender.dateComponents([.day, .year, .month], from: (asset.creationDate)!), [asset]) + assetsByDate.append(value) + assetsByDateIndex += 1 + } + } else if assetsByDate.count == assetsByDateIndex { + let value = (calender.dateComponents([.day, .year, .month], from: (asset.creationDate)!), [asset]) + assetsByDate.append(value) + assetsByDateIndex += 1 + } + } + albumDateSectionList = assetsByDate.map { AssetDateSection(creationDate: calender.date(from: $0.0) ?? Date(timeIntervalSince1970: 0), assetResult: $0.1) } + + return albumDateSectionList + } +} diff --git a/NohanaImagePicker/AssetListSelectableDateSectionController.swift b/NohanaImagePicker/AssetListSelectableDateSectionController.swift index 4dae797..f58f615 100644 --- a/NohanaImagePicker/AssetListSelectableDateSectionController.swift +++ b/NohanaImagePicker/AssetListSelectableDateSectionController.swift @@ -46,37 +46,7 @@ class AssetListSelectableDateSectionController: UICollectionViewController, UICo setUpActivityIndicator() DispatchQueue.main.async { [weak self] in guard let self = self else { return } - // TODO: DI - self.dateSectionList = { [weak self] in - guard let self = self else { return [] } - var albumDateSectionList = [AssetDateSection]() - let options = PHFetchOptions() - options.predicate = NSPredicate(format: "mediaType == %ld", PHAssetMediaType.image.rawValue) - options.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: true)] - let fetchAssetlist = PHAsset.fetchAssets(in: self.photoKitAssetList.assetList, options: options) - let allAssets = fetchAssetlist.objects(at: IndexSet(0.. 0 { - if assetsByDate[assetsByDateIndex - 1].0 == calender.dateComponents([.day, .year, .month], from: (asset.creationDate)!) { - assetsByDate[assetsByDateIndex - 1].1.append(asset) - } else { - let value = (calender.dateComponents([.day, .year, .month], from: (asset.creationDate)!), [asset]) - assetsByDate.append(value) - assetsByDateIndex += 1 - } - } else if assetsByDate.count == assetsByDateIndex { - let value = (calender.dateComponents([.day, .year, .month], from: (asset.creationDate)!), [asset]) - assetsByDate.append(value) - assetsByDateIndex += 1 - } - } - albumDateSectionList = assetsByDate.map { AssetDateSection(creationDate: calender.date(from: $0.0) ?? Date(timeIntervalSince1970: 0), assetResult: $0.1) } - - return albumDateSectionList - }() + self.dateSectionList = AssetDateSectionCreater().createSections(assetList: self.photoKitAssetList.assetList, options: PhotoKitAssetList.fetchOptions(self.photoKitAssetList.mediaType)) self.isLoading = false self.collectionView?.reloadData() self.isFirstAppearance = true diff --git a/NohanaImagePicker/PhotoKitAssetList.swift b/NohanaImagePicker/PhotoKitAssetList.swift index c9633a2..5a81eee 100644 --- a/NohanaImagePicker/PhotoKitAssetList.swift +++ b/NohanaImagePicker/PhotoKitAssetList.swift @@ -18,7 +18,7 @@ import Photos open class PhotoKitAssetList: ItemList { - fileprivate let mediaType: MediaType + public let mediaType: MediaType public let assetList: PHAssetCollection fileprivate var fetchResult: PHFetchResult! From 6cb9b13d58b02a0be73fb9c1a5bcec8da8dda5e6 Mon Sep 17 00:00:00 2001 From: "naoto.suzuki" Date: Wed, 10 Nov 2021 16:36:34 +0900 Subject: [PATCH 11/26] Fixed process. --- .../AssetDateSectionHeaderView.swift | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/NohanaImagePicker/AssetDateSectionHeaderView.swift b/NohanaImagePicker/AssetDateSectionHeaderView.swift index cd245f3..aaf5b43 100644 --- a/NohanaImagePicker/AssetDateSectionHeaderView.swift +++ b/NohanaImagePicker/AssetDateSectionHeaderView.swift @@ -29,27 +29,19 @@ class AssetDateSectionHeaderView: UICollectionReusableView { @IBAction func didPushPickButton(_ sender: UIButton) { let firstButtonState = sender.isSelected - var isNotPickedAsset = false - let maxSelectionCount = min(assets.count, nohanaImagePickerController?.maximumNumberOfSelection ?? assets.count) - for index in 0.. Date: Fri, 29 Oct 2021 16:17:13 +0900 Subject: [PATCH 12/26] Fixed background color. --- NohanaImagePicker/AssetDetailListViewController.swift | 5 +++++ NohanaImagePicker/MomentDetailListViewController.swift | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/NohanaImagePicker/AssetDetailListViewController.swift b/NohanaImagePicker/AssetDetailListViewController.swift index dfe1b4a..f7f3d8f 100644 --- a/NohanaImagePicker/AssetDetailListViewController.swift +++ b/NohanaImagePicker/AssetDetailListViewController.swift @@ -31,6 +31,11 @@ class AssetDetailListViewController: AssetListViewController, DetailListViewCont override var cellSize: CGSize { return Size.screenRectWithoutAppBar(self).size } + + override func loadView() { + super.loadView() + self.collectionView.backgroundColor = .black + } override func viewDidLoad() { super.viewDidLoad() diff --git a/NohanaImagePicker/MomentDetailListViewController.swift b/NohanaImagePicker/MomentDetailListViewController.swift index 722fdd6..31f6788 100644 --- a/NohanaImagePicker/MomentDetailListViewController.swift +++ b/NohanaImagePicker/MomentDetailListViewController.swift @@ -35,6 +35,11 @@ final class MomentDetailListViewController: UICollectionViewController, UICollec weak var nohanaImagePickerController: NohanaImagePickerController? var momentInfoSection: MomentInfoSection? var isFirstAppearance = true + + override func loadView() { + super.loadView() + self.collectionView.backgroundColor = .black + } override func viewDidLoad() { super.viewDidLoad() From c7bb1d683cd70c52578645f981ee3ae572057b96 Mon Sep 17 00:00:00 2001 From: "naoto.suzuki" Date: Tue, 16 Nov 2021 10:37:28 +0900 Subject: [PATCH 13/26] Modified reload date section process. --- ...setListSelectableDateSectionController.swift | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/NohanaImagePicker/AssetListSelectableDateSectionController.swift b/NohanaImagePicker/AssetListSelectableDateSectionController.swift index f58f615..3cc9564 100644 --- a/NohanaImagePicker/AssetListSelectableDateSectionController.swift +++ b/NohanaImagePicker/AssetListSelectableDateSectionController.swift @@ -227,11 +227,18 @@ extension AssetListSelectableDateSectionController: AssetDateSectionHeaderViewDe extension AssetListSelectableDateSectionController: AssetCellDelegate { func didPushPickButton(cell: AssetCell) { if let indexPath = collectionView.indexPath(for: cell) { - UIView.animate(withDuration: 0) { [weak self] in - self?.collectionView.performBatchUpdates({ [weak self] in - let indexSet = IndexSet(integer: indexPath.section) - self?.collectionView.reloadSections(indexSet) - }, completion: nil) + if #available(iOS 9.0, *) { + let rowResetIndexPath = IndexPath(row: 0, section: indexPath.section) + let header = collectionView.supplementaryView(forElementKind: UICollectionView.elementKindSectionHeader, at: rowResetIndexPath) as? AssetDateSectionHeaderView + let assets = dateSectionList[indexPath.section].assetResult.map { PhotoKitAsset(asset: $0) } + header?.update(assets: assets, indexPath: indexPath, nohanaImagePickerController: nohanaImagePickerController!) + } else { + UIView.animate(withDuration: 0) { [weak self] in + self?.collectionView.performBatchUpdates({ [weak self] in + let indexSet = IndexSet(integer: indexPath.section) + self?.collectionView.reloadSections(indexSet) + }, completion: nil) + } } } } From e0cfadba35cd4a97efa1c0fb6ca616cd8e5fa041 Mon Sep 17 00:00:00 2001 From: "naoto.suzuki" Date: Tue, 16 Nov 2021 11:55:19 +0900 Subject: [PATCH 14/26] Fixed added check canPickAsset. --- NohanaImagePicker/AssetDateSectionHeaderView.swift | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/NohanaImagePicker/AssetDateSectionHeaderView.swift b/NohanaImagePicker/AssetDateSectionHeaderView.swift index aaf5b43..aa88f21 100644 --- a/NohanaImagePicker/AssetDateSectionHeaderView.swift +++ b/NohanaImagePicker/AssetDateSectionHeaderView.swift @@ -28,15 +28,18 @@ class AssetDateSectionHeaderView: UICollectionReusableView { weak var delegate: AssetDateSectionHeaderViewDelegate? @IBAction func didPushPickButton(_ sender: UIButton) { + guard let nohanaImagePickerController = nohanaImagePickerController else { return } let firstButtonState = sender.isSelected for asset in assets { + guard nohanaImagePickerController.canPickAsset(asset) else { continue } if firstButtonState { - _ = nohanaImagePickerController?.pickedAssetList.drop(asset: asset) + _ = nohanaImagePickerController.pickedAssetList.drop(asset: asset) sender.isSelected = false } else { - if nohanaImagePickerController?.pickedAssetList.pick(asset: asset) ?? false { + + if nohanaImagePickerController.pickedAssetList.pick(asset: asset) { sender.isSelected = true - } else if nohanaImagePickerController?.pickedAssetList.count == nohanaImagePickerController?.maximumNumberOfSelection { + } else if nohanaImagePickerController.pickedAssetList.count == nohanaImagePickerController.maximumNumberOfSelection { sender.isSelected = false break } From 2bbb2f51cd714cbd2de6eb10f318b1efd5080773 Mon Sep 17 00:00:00 2001 From: "naoto.suzuki" Date: Tue, 16 Nov 2021 14:29:40 +0900 Subject: [PATCH 15/26] Added delegate function. --- Demo/DemoListViewController.swift | 4 ++++ .../AssetDateSectionHeaderView.swift | 15 ++++++++++++++- ...AssetListSelectableDateSectionController.swift | 5 +---- .../NohanaImagePickerController.swift | 2 +- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/Demo/DemoListViewController.swift b/Demo/DemoListViewController.swift index 5336d48..8e3e17f 100644 --- a/Demo/DemoListViewController.swift +++ b/Demo/DemoListViewController.swift @@ -177,6 +177,10 @@ class DemoListViewController: UITableViewController, NohanaImagePickerController func nohanaImagePicker(_ picker: NohanaImagePickerController, didSelectPhotoKitAsset asset: PHAsset) { print("🐷\(#function)\n\tasset = \(asset)\n\t") } + + func nohanaImagePicker(_ picker: NohanaImagePickerController, didSelectAssetDateSectionAssets assets: [PHAsset], date: Date?) { + print("🐷\(#function)\n\tasset = \(assets)\n\tDate = \(String(describing: date))") + } func nohanaImagePicker(_ picker: NohanaImagePickerController, didSelectPhotoKitAssetList assetList: PHAssetCollection) { print("🐷\(#function)\n\t\tassetList = \(assetList)\n\t") diff --git a/NohanaImagePicker/AssetDateSectionHeaderView.swift b/NohanaImagePicker/AssetDateSectionHeaderView.swift index aa88f21..ff06f58 100644 --- a/NohanaImagePicker/AssetDateSectionHeaderView.swift +++ b/NohanaImagePicker/AssetDateSectionHeaderView.swift @@ -21,8 +21,20 @@ protocol AssetDateSectionHeaderViewDelegate: AnyObject { } class AssetDateSectionHeaderView: UICollectionReusableView { - @IBOutlet weak var dateLabel: UILabel! + @IBOutlet weak private var dateLabel: UILabel! @IBOutlet weak var pickButton: UIButton! + var date: Date? { + didSet { + if let dete = date { + let formatter = DateFormatter() + formatter.dateStyle = .long + formatter.timeStyle = DateFormatter.Style.none + dateLabel.text = formatter.string(from: dete) + } else { + dateLabel.text = "" + } + } + } var assets = [Asset]() weak var nohanaImagePickerController: NohanaImagePickerController? weak var delegate: AssetDateSectionHeaderViewDelegate? @@ -46,6 +58,7 @@ class AssetDateSectionHeaderView: UICollectionReusableView { } } delegate?.didPushPickButton() + nohanaImagePickerController.delegate?.nohanaImagePicker?(nohanaImagePickerController, didSelectAssetDateSectionAssets: assets.compactMap { ($0 as? PhotoKitAsset)?.originalAsset }, date: date) } func update(assets: [Asset], indexPath: IndexPath, nohanaImagePickerController: NohanaImagePickerController) { diff --git a/NohanaImagePicker/AssetListSelectableDateSectionController.swift b/NohanaImagePicker/AssetListSelectableDateSectionController.swift index 3cc9564..87369f2 100644 --- a/NohanaImagePicker/AssetListSelectableDateSectionController.swift +++ b/NohanaImagePicker/AssetListSelectableDateSectionController.swift @@ -141,10 +141,7 @@ class AssetListSelectableDateSectionController: UICollectionViewController, UICo let nohanaImagePickerController = nohanaImagePickerController else { fatalError("failed to create AssetDateSectionHeader") } - let formatter = DateFormatter() - formatter.dateStyle = .long - formatter.timeStyle = DateFormatter.Style.none - header.dateLabel.text = formatter.string(from: album.creationDate) + header.date = album.creationDate header.delegate = self let assets = dateSectionList[indexPath.section].assetResult.map { PhotoKitAsset(asset: $0) } header.update(assets: assets, indexPath: indexPath, nohanaImagePickerController: nohanaImagePickerController) diff --git a/NohanaImagePicker/NohanaImagePickerController.swift b/NohanaImagePicker/NohanaImagePickerController.swift index 2856ef1..080872c 100644 --- a/NohanaImagePicker/NohanaImagePickerController.swift +++ b/NohanaImagePicker/NohanaImagePickerController.swift @@ -29,12 +29,12 @@ public enum MediaType: Int { @objc optional func nohanaImagePicker(_ picker: NohanaImagePickerController, willDropPhotoKitAsset asset: PHAsset, pickedAssetsCount: Int) -> Bool @objc optional func nohanaImagePicker(_ picker: NohanaImagePickerController, didDropPhotoKitAsset asset: PHAsset, pickedAssetsCount: Int) @objc optional func nohanaImagePicker(_ picker: NohanaImagePickerController, didSelectPhotoKitAsset asset: PHAsset) + @objc optional func nohanaImagePicker(_ picker: NohanaImagePickerController, didSelectAssetDateSectionAssets assets: [PHAsset], date: Date?) @objc optional func nohanaImagePicker(_ picker: NohanaImagePickerController, didSelectPhotoKitAssetList assetList: PHAssetCollection) @objc optional func nohanaImagePickerDidSelectMoment(_ picker: NohanaImagePickerController) -> Void @objc optional func nohanaImagePicker(_ picker: NohanaImagePickerController, assetListViewController: UICollectionViewController, cell: UICollectionViewCell, indexPath: IndexPath, photoKitAsset: PHAsset) -> UICollectionViewCell @objc optional func nohanaImagePicker(_ picker: NohanaImagePickerController, assetDetailListViewController: UICollectionViewController, cell: UICollectionViewCell, indexPath: IndexPath, photoKitAsset: PHAsset) -> UICollectionViewCell @objc optional func nohanaImagePicker(_ picker: NohanaImagePickerController, assetDetailListViewController: UICollectionViewController, didChangeAssetDetailPage indexPath: IndexPath, photoKitAsset: PHAsset) - } open class NohanaImagePickerController: UIViewController { From 6d2383ca423580d4bdda546c10b96745a713d5fc Mon Sep 17 00:00:00 2001 From: tyokujin <48660748+tyokujin@users.noreply.github.com> Date: Wed, 17 Nov 2021 10:49:03 +0900 Subject: [PATCH 16/26] Update NohanaImagePicker/AssetDateSectionHeaderView.swift Co-authored-by: a.yoshimoto --- NohanaImagePicker/AssetDateSectionHeaderView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NohanaImagePicker/AssetDateSectionHeaderView.swift b/NohanaImagePicker/AssetDateSectionHeaderView.swift index ff06f58..ca96d53 100644 --- a/NohanaImagePicker/AssetDateSectionHeaderView.swift +++ b/NohanaImagePicker/AssetDateSectionHeaderView.swift @@ -22,7 +22,7 @@ protocol AssetDateSectionHeaderViewDelegate: AnyObject { class AssetDateSectionHeaderView: UICollectionReusableView { @IBOutlet weak private var dateLabel: UILabel! - @IBOutlet weak var pickButton: UIButton! + @IBOutlet weak private var pickButton: UIButton! var date: Date? { didSet { if let dete = date { From e64e7b24f6363d9d07ef5cc4cda161aaffbe7313 Mon Sep 17 00:00:00 2001 From: "naoto.suzuki" Date: Wed, 17 Nov 2021 11:38:56 +0900 Subject: [PATCH 17/26] Fixed picked image reference. --- NohanaImagePicker/AssetDateSectionHeaderView.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NohanaImagePicker/AssetDateSectionHeaderView.swift b/NohanaImagePicker/AssetDateSectionHeaderView.swift index ca96d53..3580b08 100644 --- a/NohanaImagePicker/AssetDateSectionHeaderView.swift +++ b/NohanaImagePicker/AssetDateSectionHeaderView.swift @@ -65,8 +65,8 @@ class AssetDateSectionHeaderView: UICollectionReusableView { self.assets = assets self.nohanaImagePickerController = nohanaImagePickerController if pickButton.image(for: UIControl.State()) == nil, pickButton.image(for: .selected) == nil { - let droppedImage: UIImage? = nohanaImagePickerController.config.image.droppedSmall ?? UIImage(named: "btn_select_l", in: nohanaImagePickerController.assetBundle, compatibleWith: nil) - let pickedImage: UIImage? = nohanaImagePickerController.config.image.pickedSmall ?? UIImage(named: "btn_selected_l", in: nohanaImagePickerController.assetBundle, compatibleWith: nil) + let droppedImage: UIImage? = nohanaImagePickerController.config.image.droppedLarge ?? UIImage(named: "btn_select_l", in: nohanaImagePickerController.assetBundle, compatibleWith: nil) + let pickedImage: UIImage? = nohanaImagePickerController.config.image.pickedLarge ?? UIImage(named: "btn_selected_l", in: nohanaImagePickerController.assetBundle, compatibleWith: nil) pickButton.setImage(droppedImage, for: UIControl.State()) pickButton.setImage(pickedImage, for: .selected) } From 63d1a68dbde0bc1c3c3546d6b472a55a20bbb612 Mon Sep 17 00:00:00 2001 From: "naoto.suzuki" Date: Fri, 19 Nov 2021 15:49:58 +0900 Subject: [PATCH 18/26] Modified date section size. --- NohanaImagePicker/AssetListSelectableDateSection.storyboard | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NohanaImagePicker/AssetListSelectableDateSection.storyboard b/NohanaImagePicker/AssetListSelectableDateSection.storyboard index b7897df..dd8e568 100644 --- a/NohanaImagePicker/AssetListSelectableDateSection.storyboard +++ b/NohanaImagePicker/AssetListSelectableDateSection.storyboard @@ -19,11 +19,11 @@ - + - + From 7d40b0a2f9f8df65837e0fcc75ab4e20b283a418 Mon Sep 17 00:00:00 2001 From: "atsushi.yoshimoto" Date: Fri, 19 Nov 2021 12:36:25 +0900 Subject: [PATCH 19/26] Fixed navigationbar appearance. --- NohanaImagePicker/NohanaImagePicker.storyboard | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/NohanaImagePicker/NohanaImagePicker.storyboard b/NohanaImagePicker/NohanaImagePicker.storyboard index 986a9e1..87779b1 100644 --- a/NohanaImagePicker/NohanaImagePicker.storyboard +++ b/NohanaImagePicker/NohanaImagePicker.storyboard @@ -1,9 +1,9 @@ - + - + @@ -282,6 +282,10 @@ + + + + @@ -301,6 +305,10 @@ + + + + From 4a4f9c0d52e6547b1e79561f2cb0000168f99920 Mon Sep 17 00:00:00 2001 From: "atsushi.yoshimoto" Date: Fri, 19 Nov 2021 15:50:49 +0900 Subject: [PATCH 20/26] Fixed toolbar appearance. --- NohanaImagePicker/NohanaImagePicker.storyboard | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/NohanaImagePicker/NohanaImagePicker.storyboard b/NohanaImagePicker/NohanaImagePicker.storyboard index 87779b1..da8c37a 100644 --- a/NohanaImagePicker/NohanaImagePicker.storyboard +++ b/NohanaImagePicker/NohanaImagePicker.storyboard @@ -288,6 +288,13 @@ + + + + + + + @@ -310,6 +317,13 @@ + + + + + + + From 01b7b688a1d444fd71292f02eb6bba373238c753 Mon Sep 17 00:00:00 2001 From: "naoto.suzuki" Date: Fri, 19 Nov 2021 17:06:01 +0900 Subject: [PATCH 21/26] Sorted ascending. --- .../AlbumListViewController.swift | 1 + ...tListSelectableDateSectionController.swift | 19 +------------------ NohanaImagePicker/PhotoKitAssetList.swift | 8 ++++++-- 3 files changed, 8 insertions(+), 20 deletions(-) diff --git a/NohanaImagePicker/AlbumListViewController.swift b/NohanaImagePicker/AlbumListViewController.swift index 5488470..9348368 100644 --- a/NohanaImagePicker/AlbumListViewController.swift +++ b/NohanaImagePicker/AlbumListViewController.swift @@ -196,6 +196,7 @@ class AlbumListViewController: UITableViewController, EmptyIndicatable, Activity assetListViewController.nohanaImagePickerController = nohanaImagePickerController case "toAssetListViewSelectableDateSectionController": let assetListSelectableDateSectionController = segue.destination as! AssetListSelectableDateSectionController + photoKitAlbumList[tableView.indexPathForSelectedRow!.row].sortDate(ascending: false) assetListSelectableDateSectionController.photoKitAssetList = photoKitAlbumList[tableView.indexPathForSelectedRow!.row] assetListSelectableDateSectionController.nohanaImagePickerController = nohanaImagePickerController default: diff --git a/NohanaImagePicker/AssetListSelectableDateSectionController.swift b/NohanaImagePicker/AssetListSelectableDateSectionController.swift index 87369f2..3080532 100644 --- a/NohanaImagePicker/AssetListSelectableDateSectionController.swift +++ b/NohanaImagePicker/AssetListSelectableDateSectionController.swift @@ -22,7 +22,6 @@ class AssetListSelectableDateSectionController: UICollectionViewController, UICo weak var nohanaImagePickerController: NohanaImagePickerController? var photoKitAssetList: PhotoKitAssetList! var dateSectionList: [AssetDateSection] = [] - var isFirstAppearance = true var cellSize: CGSize { guard let nohanaImagePickerController = nohanaImagePickerController else { @@ -46,11 +45,9 @@ class AssetListSelectableDateSectionController: UICollectionViewController, UICo setUpActivityIndicator() DispatchQueue.main.async { [weak self] in guard let self = self else { return } - self.dateSectionList = AssetDateSectionCreater().createSections(assetList: self.photoKitAssetList.assetList, options: PhotoKitAssetList.fetchOptions(self.photoKitAssetList.mediaType)) + self.dateSectionList = AssetDateSectionCreater().createSections(assetList: self.photoKitAssetList.assetList, options: PhotoKitAssetList.fetchOptions(self.photoKitAssetList.mediaType, ascending: false)) self.isLoading = false self.collectionView?.reloadData() - self.isFirstAppearance = true - self.scrollCollectionViewToInitialPosition() } } @@ -60,7 +57,6 @@ class AssetListSelectableDateSectionController: UICollectionViewController, UICo setToolbarTitle(nohanaImagePickerController) } collectionView?.reloadData() - scrollCollectionViewToInitialPosition() } func updateTitle() { @@ -77,19 +73,6 @@ class AssetListSelectableDateSectionController: UICollectionViewController, UICo } } - func scrollCollectionViewToInitialPosition() { - guard isFirstAppearance else { - return - } - let lastSection = dateSectionList.count - 1 - guard lastSection >= 0 else { - return - } - let indexPath = IndexPath(item: dateSectionList[lastSection].assetResult.count - 1, section: lastSection) - scrollCollectionView(to: indexPath) - isFirstAppearance = false - } - // MARK: - UICollectionViewDataSource override func numberOfSections(in collectionView: UICollectionView) -> Int { diff --git a/NohanaImagePicker/PhotoKitAssetList.swift b/NohanaImagePicker/PhotoKitAssetList.swift index 5a81eee..bb47f5e 100644 --- a/NohanaImagePicker/PhotoKitAssetList.swift +++ b/NohanaImagePicker/PhotoKitAssetList.swift @@ -40,12 +40,12 @@ open class PhotoKitAssetList: ItemList { return assetList.startDate } - class func fetchOptions(_ mediaType: MediaType) -> PHFetchOptions { + class func fetchOptions(_ mediaType: MediaType, ascending: Bool = true) -> PHFetchOptions { let options = PHFetchOptions() switch mediaType { case .photo: options.predicate = NSPredicate(format: "mediaType == %ld", PHAssetMediaType.image.rawValue) - options.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: true)] + options.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: ascending)] default: fatalError("not supported .Video and .Any yet") } @@ -59,6 +59,10 @@ open class PhotoKitAssetList: ItemList { } } + open func sortDate(ascending: Bool) { + fetchResult = PHAsset.fetchAssets(in: assetList, options: PhotoKitAssetList.fetchOptions(mediaType, ascending: ascending)) + } + open subscript (index: Int) -> Item { return Item(asset: fetchResult.object(at: index)) } From be122ce27c38c736b86514586a335b15756685bd Mon Sep 17 00:00:00 2001 From: "naoto.suzuki" Date: Fri, 19 Nov 2021 17:26:35 +0900 Subject: [PATCH 22/26] Modified ascending process. --- NohanaImagePicker/AlbumListViewController.swift | 3 +-- NohanaImagePicker/NohanaImagePickerController.swift | 1 + NohanaImagePicker/PhotoKitAlbumList.swift | 6 ++++-- NohanaImagePicker/PhotoKitAssetList.swift | 10 ++++------ 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/NohanaImagePicker/AlbumListViewController.swift b/NohanaImagePicker/AlbumListViewController.swift index 9348368..cc909ee 100644 --- a/NohanaImagePicker/AlbumListViewController.swift +++ b/NohanaImagePicker/AlbumListViewController.swift @@ -161,7 +161,7 @@ class AlbumListViewController: UITableViewController, EmptyIndicatable, Activity ) let albumCount = albumList.count if albumCount > 0 { - let lastAsset = albumList[albumCount - 1] + let lastAsset = nohanaImagePickerController?.canPickDateSection ?? false ? albumList[0] : albumList[albumCount - 1] lastAsset.image(targetSize: imageSize, handler: { (imageData) -> Void in DispatchQueue.main.async(execute: { () -> Void in if let imageData = imageData { @@ -196,7 +196,6 @@ class AlbumListViewController: UITableViewController, EmptyIndicatable, Activity assetListViewController.nohanaImagePickerController = nohanaImagePickerController case "toAssetListViewSelectableDateSectionController": let assetListSelectableDateSectionController = segue.destination as! AssetListSelectableDateSectionController - photoKitAlbumList[tableView.indexPathForSelectedRow!.row].sortDate(ascending: false) assetListSelectableDateSectionController.photoKitAssetList = photoKitAlbumList[tableView.indexPathForSelectedRow!.row] assetListSelectableDateSectionController.nohanaImagePickerController = nohanaImagePickerController default: diff --git a/NohanaImagePicker/NohanaImagePickerController.swift b/NohanaImagePicker/NohanaImagePickerController.swift index 080872c..9826ef5 100644 --- a/NohanaImagePicker/NohanaImagePickerController.swift +++ b/NohanaImagePicker/NohanaImagePickerController.swift @@ -121,6 +121,7 @@ open class NohanaImagePickerController: UIViewController { assetCollectionSubtypes: assetCollectionSubtypes, mediaType: mediaType, shouldShowEmptyAlbum: shouldShowEmptyAlbum, + ascending: !canPickDateSection, handler: { [weak albumListViewController] in DispatchQueue.main.async(execute: { () -> Void in albumListViewController?.isLoading = false diff --git a/NohanaImagePicker/PhotoKitAlbumList.swift b/NohanaImagePicker/PhotoKitAlbumList.swift index 994ee44..bca1843 100644 --- a/NohanaImagePicker/PhotoKitAlbumList.swift +++ b/NohanaImagePicker/PhotoKitAlbumList.swift @@ -22,14 +22,16 @@ public class PhotoKitAlbumList: ItemList { private let assetCollectionSubtypes: [PHAssetCollectionSubtype] private let mediaType: MediaType private var shouldShowEmptyAlbum: Bool + private let ascending: Bool // MARK: - init - init(assetCollectionTypes: [PHAssetCollectionType], assetCollectionSubtypes: [PHAssetCollectionSubtype], mediaType: MediaType, shouldShowEmptyAlbum: Bool, handler:(() -> Void)?) { + init(assetCollectionTypes: [PHAssetCollectionType], assetCollectionSubtypes: [PHAssetCollectionSubtype], mediaType: MediaType, shouldShowEmptyAlbum: Bool, ascending: Bool, handler:(() -> Void)?) { self.assetCollectionTypes = assetCollectionTypes self.assetCollectionSubtypes = assetCollectionSubtypes self.mediaType = mediaType self.shouldShowEmptyAlbum = shouldShowEmptyAlbum + self.ascending = ascending update { () -> Void in if let handler = handler { handler() @@ -59,7 +61,7 @@ public class PhotoKitAlbumList: ItemList { fetchResult.enumerateObjects({ (album, index, stop) in if self.assetCollectionSubtypes.contains(album.assetCollectionSubtype) || isAssetCollectionSubtypeAny { if self.shouldShowEmptyAlbum || PHAsset.fetchAssets(in: album, options: PhotoKitAssetList.fetchOptions(self.mediaType)).count != 0 { - tmpAlbumList.append(PhotoKitAssetList(album: album, mediaType: self.mediaType)) + tmpAlbumList.append(PhotoKitAssetList(album: album, mediaType: self.mediaType, ascending: self.ascending)) } } }) diff --git a/NohanaImagePicker/PhotoKitAssetList.swift b/NohanaImagePicker/PhotoKitAssetList.swift index bb47f5e..d70bf5c 100644 --- a/NohanaImagePicker/PhotoKitAssetList.swift +++ b/NohanaImagePicker/PhotoKitAssetList.swift @@ -20,11 +20,13 @@ open class PhotoKitAssetList: ItemList { public let mediaType: MediaType public let assetList: PHAssetCollection + private let ascending: Bool fileprivate var fetchResult: PHFetchResult! - init(album: PHAssetCollection, mediaType: MediaType) { + init(album: PHAssetCollection, mediaType: MediaType, ascending: Bool) { self.assetList = album self.mediaType = mediaType + self.ascending = ascending update() } @@ -53,16 +55,12 @@ open class PhotoKitAssetList: ItemList { } open func update(_ handler: (() -> Void)? = nil) { - fetchResult = PHAsset.fetchAssets(in: assetList, options: PhotoKitAssetList.fetchOptions(mediaType)) + fetchResult = PHAsset.fetchAssets(in: assetList, options: PhotoKitAssetList.fetchOptions(mediaType, ascending: ascending)) if let handler = handler { handler() } } - open func sortDate(ascending: Bool) { - fetchResult = PHAsset.fetchAssets(in: assetList, options: PhotoKitAssetList.fetchOptions(mediaType, ascending: ascending)) - } - open subscript (index: Int) -> Item { return Item(asset: fetchResult.object(at: index)) } From 2c4060d3165d05ad2363e71a9c5995ae16c97ccc Mon Sep 17 00:00:00 2001 From: "naoto.suzuki" Date: Fri, 19 Nov 2021 17:30:05 +0900 Subject: [PATCH 23/26] Modified header size. --- .../AssetListSelectableDateSection.storyboard | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/NohanaImagePicker/AssetListSelectableDateSection.storyboard b/NohanaImagePicker/AssetListSelectableDateSection.storyboard index dd8e568..d950361 100644 --- a/NohanaImagePicker/AssetListSelectableDateSection.storyboard +++ b/NohanaImagePicker/AssetListSelectableDateSection.storyboard @@ -17,13 +17,13 @@ - + - + @@ -70,11 +70,11 @@ - +