diff --git a/Demo/DemoListViewController.swift b/Demo/DemoListViewController.swift
index 277b42f..4f7cc78 100644
--- a/Demo/DemoListViewController.swift
+++ b/Demo/DemoListViewController.swift
@@ -16,6 +16,7 @@
import UIKit
import NohanaImagePicker
import Photos
+import PhotosUI
struct Cell {
let title: String
@@ -72,7 +73,13 @@ class DemoListViewController: UITableViewController, NohanaImagePickerController
// MARK: - Photos
func checkIfAuthorizedToAccessPhotos(_ handler: @escaping (_ isAuthorized: Bool) -> Void) {
- switch PHPhotoLibrary.authorizationStatus() {
+ let status: PHAuthorizationStatus
+ if #available(iOS 14, *) {
+ status = PHPhotoLibrary.authorizationStatus(for: .readWrite)
+ } else {
+ status = PHPhotoLibrary.authorizationStatus()
+ }
+ switch status {
case .notDetermined:
PHPhotoLibrary.requestAuthorization { status in
DispatchQueue.main.async {
@@ -238,4 +245,21 @@ class DemoListViewController: UITableViewController, NohanaImagePickerController
func nohanaImagePicker(_ picker: NohanaImagePickerController, assetDetailListViewController: UICollectionViewController, didChangeAssetDetailPage indexPath: IndexPath, photoKitAsset: PHAsset) {
print("🐷\(#function)\n\tindexPath = \(indexPath)")
}
+
+ func nohanaImagePickerDidTapAddPhotoButton(_ picker: NohanaImagePickerController) {
+ print("🐷\(#function)")
+ if #available(iOS 14, *) {
+ PHPhotoLibrary.shared().presentLimitedLibraryPicker(from: picker)
+ }
+ }
+
+ func nohanaImagePickerDidTapAuthorizeAllPhotoButton(_ picker: NohanaImagePickerController) {
+ print("🐷\(#function)")
+ guard let url = URL(string: UIApplication.openSettingsURLString),
+ UIApplication.shared.canOpenURL(url) else {
+ assertionFailure("Not able to open App privacy settings")
+ return
+ }
+ UIApplication.shared.open(url, options: [:], completionHandler: nil)
+ }
}
diff --git a/Demo/Info.plist b/Demo/Info.plist
index 36e869d..3de749b 100644
--- a/Demo/Info.plist
+++ b/Demo/Info.plist
@@ -45,5 +45,7 @@
NSPhotoLibraryUsageDescription
To pick some photos.
+ PHPhotoLibraryPreventAutomaticLimitedAccessAlert
+
diff --git a/NohanaImagePicker.xcodeproj/project.pbxproj b/NohanaImagePicker.xcodeproj/project.pbxproj
index 93471c5..4fdbb7d 100644
--- a/NohanaImagePicker.xcodeproj/project.pbxproj
+++ b/NohanaImagePicker.xcodeproj/project.pbxproj
@@ -17,6 +17,8 @@
6AD1607C27700F0C00A8B066 /* RootViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AD1607B27700F0C00A8B066 /* RootViewController.swift */; };
6AD1607F2770B23D00A8B066 /* UIApplication+Ex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AD1607E2770B23D00A8B066 /* UIApplication+Ex.swift */; };
F117F732273B6A2600E11BC7 /* AssetDateSectionCreater.swift in Sources */ = {isa = PBXBuildFile; fileRef = F117F731273B6A2600E11BC7 /* AssetDateSectionCreater.swift */; };
+ F145C5E22890F8DC0070A4E2 /* PhotoAuthorizationLimitedCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F145C5E02890F8DC0070A4E2 /* PhotoAuthorizationLimitedCell.swift */; };
+ F145C5E32890F8DC0070A4E2 /* PhotoAuthorizationLimitedCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = F145C5E12890F8DC0070A4E2 /* PhotoAuthorizationLimitedCell.xib */; };
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 */; };
@@ -99,6 +101,8 @@
6AD1607B27700F0C00A8B066 /* RootViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootViewController.swift; sourceTree = ""; };
6AD1607E2770B23D00A8B066 /* UIApplication+Ex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIApplication+Ex.swift"; sourceTree = ""; };
F117F731273B6A2600E11BC7 /* AssetDateSectionCreater.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetDateSectionCreater.swift; sourceTree = ""; };
+ F145C5E02890F8DC0070A4E2 /* PhotoAuthorizationLimitedCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoAuthorizationLimitedCell.swift; sourceTree = ""; };
+ F145C5E12890F8DC0070A4E2 /* PhotoAuthorizationLimitedCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = PhotoAuthorizationLimitedCell.xib; 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 = ""; };
@@ -233,6 +237,8 @@
F1A26CCC2738DE6A00433E9F /* AssetListSelectableDateSection.storyboard */,
F27029CD1C71C43A001647AB /* NohanaImagePicker.strings */,
F237249A1C6DCF96005D1E8A /* NohanaImagePicker.xcassets */,
+ F145C5E02890F8DC0070A4E2 /* PhotoAuthorizationLimitedCell.swift */,
+ F145C5E12890F8DC0070A4E2 /* PhotoAuthorizationLimitedCell.xib */,
);
name = Resources;
sourceTree = "";
@@ -439,6 +445,7 @@
F237249B1C6DCF96005D1E8A /* NohanaImagePicker.xcassets in Resources */,
6A8047FF276C3D77000F3B28 /* AlbumList.storyboard in Resources */,
F1A26CCD2738DE6A00433E9F /* AssetListSelectableDateSection.storyboard in Resources */,
+ F145C5E32890F8DC0070A4E2 /* PhotoAuthorizationLimitedCell.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -479,6 +486,7 @@
F2131F431C79615700797887 /* SwipeInteractionController.swift in Sources */,
F2DF3B2D1C6D780100C1C0E4 /* AssetDetailCell.swift in Sources */,
F25C69901CA27311005935D6 /* EmptyIndicatable.swift in Sources */,
+ F145C5E22890F8DC0070A4E2 /* PhotoAuthorizationLimitedCell.swift in Sources */,
F117F732273B6A2600E11BC7 /* AssetDateSectionCreater.swift in Sources */,
F2DA29771C7749D600B0A8E3 /* NotificationInfo.swift in Sources */,
F1A26CCF2738E7E400433E9F /* AssetListSelectableDateSectionController.swift in Sources */,
diff --git a/NohanaImagePicker/AssetListSelectableDateSection.storyboard b/NohanaImagePicker/AssetListSelectableDateSection.storyboard
index d3a2094..2db981a 100644
--- a/NohanaImagePicker/AssetListSelectableDateSection.storyboard
+++ b/NohanaImagePicker/AssetListSelectableDateSection.storyboard
@@ -1,9 +1,9 @@
-
+
-
+
@@ -73,8 +73,8 @@
-
-
+
+
@@ -135,7 +136,7 @@
-
+
diff --git a/NohanaImagePicker/AssetListSelectableDateSectionController.swift b/NohanaImagePicker/AssetListSelectableDateSectionController.swift
index bb619ec..07fb4ad 100644
--- a/NohanaImagePicker/AssetListSelectableDateSectionController.swift
+++ b/NohanaImagePicker/AssetListSelectableDateSectionController.swift
@@ -16,11 +16,16 @@
import Foundation
import Photos
+import UIKit
class AssetListSelectableDateSectionController: UICollectionViewController, UICollectionViewDelegateFlowLayout, ActivityIndicatable {
-
+
+ private enum Section: Int {
+ case photoAuthorizationLimited = 0
+ }
+
private let nohanaImagePickerController: NohanaImagePickerController
- let photoKitAssetList: PhotoKitAssetList
+ private var photoKitAssetList: PhotoKitAssetList
var dateSectionList: [AssetDateSection] = []
var cellSize: CGSize {
@@ -32,6 +37,25 @@ class AssetListSelectableDateSectionController: UICollectionViewController, UICo
let cellWidth = (view.frame.width - cellMargin * (CGFloat(numberOfColumns) - 1)) / CGFloat(numberOfColumns)
return CGSize(width: cellWidth, height: cellWidth)
}
+
+ private lazy var isHiddenPhotoAuthorizationLimitedCell: Bool = {
+ guard !nohanaImagePickerController.isHiddenPhotoAuthorizationLimitedView else {
+ return true
+ }
+
+ let status: PHAuthorizationStatus
+ if #available(iOS 14, *) {
+ status = PHPhotoLibrary.authorizationStatus(for: .readWrite)
+ } else {
+ status = PHPhotoLibrary.authorizationStatus()
+ }
+ switch status {
+ case .limited:
+ return false
+ default:
+ return true
+ }
+ }()
init?(coder: NSCoder, nohanaImagePickerController: NohanaImagePickerController, photoKitAssetList: PhotoKitAssetList) {
self.nohanaImagePickerController = nohanaImagePickerController
@@ -49,6 +73,8 @@ class AssetListSelectableDateSectionController: UICollectionViewController, UICo
setUpToolbarItems()
addPickPhotoKitAssetNotificationObservers()
setUpActivityIndicator()
+ collectionView.register(UINib(nibName: "PhotoAuthorizationLimitedCell", bundle: self.nohanaImagePickerController.assetBundle), forCellWithReuseIdentifier: PhotoAuthorizationLimitedCell.defaultReusableId)
+ PHPhotoLibrary.shared().register(self)
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, ascending: false))
@@ -87,21 +113,34 @@ class AssetListSelectableDateSectionController: UICollectionViewController, UICo
if let activityIndicator = activityIndicator {
updateVisibilityOfActivityIndicator(activityIndicator)
}
-
- return dateSectionList.count
+ return dateSectionList.count + 1
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
- return dateSectionList[section].assetResult.count
+ if Section(rawValue: section) == .photoAuthorizationLimited {
+ return 1
+ } else {
+ return dateSectionList[section - 1].assetResult.count
+ }
}
// MARK: - UICollectionViewDelegate
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
+ if Section(rawValue: indexPath.section) == .photoAuthorizationLimited {
+ guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: PhotoAuthorizationLimitedCell.defaultReusableId, for: indexPath) as? PhotoAuthorizationLimitedCell else {
+ fatalError("failed to dequeueReusableCellWithIdentifier(\"PhotoAuthorizationLimitedCell\")")
+ }
+ cell.delegate = self
+ let isHidden = isHiddenPhotoAuthorizationLimitedCell
+ cell.update(isHidden, nohanaImagePickerController: nohanaImagePickerController)
+ return cell
+ }
+
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "AssetCell", for: indexPath) as? AssetCell else {
fatalError("failed to dequeueReusableCellWithIdentifier(\"AssetCell\")")
}
-
+ let indexPath: IndexPath = .init(row: indexPath.row, section: indexPath.section - 1)
let asset = PhotoKitAsset(asset: dateSectionList[indexPath.section].assetResult[indexPath.row])
cell.tag = indexPath.item
cell.delegate = self
@@ -126,15 +165,20 @@ class AssetListSelectableDateSectionController: UICollectionViewController, UICo
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: "AssetDateSectionHeader", for: indexPath) as? AssetDateSectionHeaderView else {
fatalError("failed to create AssetDateSectionHeader")
}
+ if Section(rawValue: indexPath.section) == .photoAuthorizationLimited {
+ return header
+ }
+ let sectionListIndex = indexPath.section - 1
+ let album = dateSectionList[sectionListIndex]
header.date = album.creationDate
header.delegate = self
- let assets = dateSectionList[indexPath.section].assetResult.map { PhotoKitAsset(asset: $0) }
+ let assets = dateSectionList[sectionListIndex].assetResult.map { PhotoKitAsset(asset: $0) }
header.update(assets: assets, indexPath: indexPath, nohanaImagePickerController: nohanaImagePickerController)
return header
+
default:
fatalError("failed to create AssetDateSectionHeader")
}
@@ -143,9 +187,25 @@ class AssetListSelectableDateSectionController: UICollectionViewController, UICo
// MARK: - UICollectionViewDelegateFlowLayout
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
- return cellSize
+ if Section(rawValue: indexPath.section) == .photoAuthorizationLimited {
+ if isHiddenPhotoAuthorizationLimitedCell {
+ return CGSize(width: collectionView.frame.width, height: 1)
+ } else {
+ return PhotoAuthorizationLimitedCell.cellSize(nohanaImagePickerController)
+ }
+ } else {
+ return cellSize
+ }
}
+ func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
+ if Section(rawValue: section) == .photoAuthorizationLimited {
+ return .zero
+ }
+ return .init(width: .infinity, height: 44.0)
+ }
+
+
// MARK: - ActivityIndicatable
var activityIndicator: UIActivityIndicatorView?
@@ -166,12 +226,18 @@ class AssetListSelectableDateSectionController: UICollectionViewController, UICo
// MARK: - UICollectionViewDelegate
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
- nohanaImagePickerController.delegate?.nohanaImagePicker?(nohanaImagePickerController, didSelectPhotoKitAsset: dateSectionList[indexPath.section].assetResult[indexPath.row])
+
+ guard Section(rawValue: indexPath.section) != .photoAuthorizationLimited else {
+ return
+ }
+
+ let sectionListIndex = indexPath.section - 1
+ nohanaImagePickerController.delegate?.nohanaImagePicker?(nohanaImagePickerController, didSelectPhotoKitAsset: dateSectionList[sectionListIndex].assetResult[indexPath.row])
}
@available(iOS 13.0, *)
override func collectionView(_ collectionView: UICollectionView, contextMenuConfigurationForItemAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? {
- let asset = PhotoKitAsset(asset: dateSectionList[indexPath.section].assetResult[indexPath.row])
+ let asset = PhotoKitAsset(asset: dateSectionList[indexPath.section - 1].assetResult[indexPath.row])
if let cell = collectionView.cellForItem(at: indexPath) as? AssetCell {
return UIContextMenuConfiguration(identifier: indexPath as NSCopying, previewProvider: { [weak self] in
// Create a preview view controller and return it
@@ -221,21 +287,23 @@ class AssetListSelectableDateSectionController: UICollectionViewController, UICo
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let selectedIndexPath = collectionView?.indexPathsForSelectedItems?.first,
- selectedIndexPath.section < dateSectionList.count else {
+ selectedIndexPath.section != 0,
+ selectedIndexPath.section - 1 < dateSectionList.count else {
return
}
var assetListDetailCurrentRow = 0
- for section in 0..<(selectedIndexPath.section + 1) {
- if selectedIndexPath.section == section {
+ for section in 0..<(selectedIndexPath.section) {
+ if selectedIndexPath.section == (section + 1) {
assetListDetailCurrentRow += selectedIndexPath.row
} else {
assetListDetailCurrentRow += dateSectionList[section].assetResult.count
}
}
+
if assetListDetailCurrentRow >= photoKitAssetList.count {
assetListDetailCurrentRow = photoKitAssetList.count - 1
}
-
+
let assetListDetailViewController = segue.destination as! AssetDetailListViewController
assetListDetailViewController.currentIndexPath = IndexPath(item: assetListDetailCurrentRow, section: 0)
}
@@ -261,7 +329,7 @@ extension AssetListSelectableDateSectionController: AssetCellDelegate {
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) }
+ let assets = dateSectionList[indexPath.section - 1].assetResult.map { PhotoKitAsset(asset: $0) }
header?.update(assets: assets, indexPath: indexPath, nohanaImagePickerController: nohanaImagePickerController)
} else {
UIView.animate(withDuration: 0) { [weak self] in
@@ -275,3 +343,45 @@ extension AssetListSelectableDateSectionController: AssetCellDelegate {
updateDoneBarButtonColor()
}
}
+
+// MARK: - PhotoAuthorizationLimitedCellDeletate
+
+extension AssetListSelectableDateSectionController: PhotoAuthorizationLimitedCellDeletate {
+ func didSelectAddPhotoButton(_ cell: PhotoAuthorizationLimitedCell) {
+ nohanaImagePickerController.delegate?.nohanaImagePickerDidTapAddPhotoButton?(nohanaImagePickerController)
+ }
+
+ func didSelectAuthorizeAllPhotoButton(_ cell: PhotoAuthorizationLimitedCell) {
+ nohanaImagePickerController.delegate?.nohanaImagePickerDidTapAuthorizeAllPhotoButton?(nohanaImagePickerController)
+ }
+}
+
+extension String {
+ func height(withConstrainedWidth width: CGFloat, font: UIFont = .systemFont(ofSize: 13.5)) -> CGFloat {
+ let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude)
+ let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: font], context: nil)
+
+ return ceil(boundingBox.height)
+ }
+
+ func width(withConstrainedHeight height: CGFloat, font: UIFont) -> CGFloat {
+ let constraintRect = CGSize(width: .greatestFiniteMagnitude, height: height)
+ let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: font], context: nil)
+
+ return ceil(boundingBox.width)
+ }
+}
+
+// MARK: - PHPhotoLibraryChangeObserver
+
+extension AssetListSelectableDateSectionController: PHPhotoLibraryChangeObserver {
+ func photoLibraryDidChange(_ changeInstance: PHChange) {
+ DispatchQueue.main.async { [weak self] in
+ guard let self = self else { return }
+ self.photoKitAssetList = PhotoKitAssetList(album: self.photoKitAssetList.assetList, mediaType: self.photoKitAssetList.mediaType, ascending: false)
+ self.dateSectionList = AssetDateSectionCreater().createSections(assetList: self.photoKitAssetList.assetList, options: PhotoKitAssetList.fetchOptions(self.photoKitAssetList.mediaType, ascending: false))
+ self.isLoading = false
+ self.collectionView?.reloadData()
+ }
+ }
+}
diff --git a/NohanaImagePicker/NohanaImagePickerController.swift b/NohanaImagePicker/NohanaImagePickerController.swift
index 4c98908..c8b5443 100644
--- a/NohanaImagePicker/NohanaImagePickerController.swift
+++ b/NohanaImagePicker/NohanaImagePickerController.swift
@@ -35,6 +35,8 @@ public enum MediaType: Int {
@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)
+ @objc optional func nohanaImagePickerDidTapAddPhotoButton(_ picker: NohanaImagePickerController)
+ @objc optional func nohanaImagePickerDidTapAuthorizeAllPhotoButton(_ picker: NohanaImagePickerController)
}
open class NohanaImagePickerController: UIViewController {
@@ -57,6 +59,7 @@ open class NohanaImagePickerController: UIViewController {
.font: UIFont.systemFont(ofSize: 17, weight: .semibold)
]
}()
+ open var isHiddenPhotoAuthorizationLimitedView: Bool = false
lazy var assetBundle: Bundle = {
let bundle = Bundle(for: type(of: self))
if let path = bundle.path(forResource: "NohanaImagePicker", ofType: "bundle") {
diff --git a/NohanaImagePicker/PhotoAuthorizationLimitedCell.swift b/NohanaImagePicker/PhotoAuthorizationLimitedCell.swift
new file mode 100644
index 0000000..288f2c7
--- /dev/null
+++ b/NohanaImagePicker/PhotoAuthorizationLimitedCell.swift
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2022 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
+
+protocol PhotoAuthorizationLimitedCellDeletate {
+ func didSelectAddPhotoButton(_ cell: PhotoAuthorizationLimitedCell)
+ func didSelectAuthorizeAllPhotoButton(_ cell: PhotoAuthorizationLimitedCell)
+}
+
+class PhotoAuthorizationLimitedCell: UICollectionViewCell {
+
+ static var defaultReusableId: String {
+ String(describing: self)
+ }
+
+ var delegate: PhotoAuthorizationLimitedCellDeletate?
+
+ @IBOutlet weak private var containerView: UIStackView!
+ @IBOutlet weak private var attentionLabel: UILabel!
+ @IBOutlet weak private var addPhotoButton: UIButton! {
+ didSet {
+ self.addPhotoButton.layer.cornerRadius = 6
+ self.addPhotoButton.layer.borderColor = UIColor(red: 187/255, green: 187/255, blue: 187/255, alpha: 1).cgColor
+ self.addPhotoButton.layer.borderWidth = 1
+ }
+ }
+ @IBOutlet weak private var authorizeAllPhotoButton: UIButton! {
+ didSet {
+ self.authorizeAllPhotoButton.layer.cornerRadius = 6
+ self.authorizeAllPhotoButton.layer.borderColor = UIColor(red: 187/255, green: 187/255, blue: 187/255, alpha: 1).cgColor
+ self.authorizeAllPhotoButton.layer.borderWidth = 1
+ }
+ }
+
+ override func awakeFromNib() {
+ super.awakeFromNib()
+ // Initialization code
+ }
+
+ @IBAction func tappedAddPhotoButton(_ sender: UIButton) {
+ delegate?.didSelectAddPhotoButton(self)
+ }
+
+ @IBAction func tappedAuthorizeAllPhotoButton(_ sender: UIButton) {
+ delegate?.didSelectAuthorizeAllPhotoButton(self)
+ }
+
+ func update(_ isHidden: Bool, nohanaImagePickerController: NohanaImagePickerController) {
+
+ containerView.isHidden = isHidden
+ attentionLabel.text = NSLocalizedString(
+ "albumlist.menu.description",
+ tableName: "NohanaImagePicker",
+ bundle: nohanaImagePickerController.assetBundle,
+ comment: ""
+ )
+
+ addPhotoButton.setTitle(
+ NSLocalizedString(
+ "albumlist.menu.addPhoto.title",
+ tableName: "NohanaImagePicker",
+ bundle: nohanaImagePickerController.assetBundle,
+ comment: ""
+ ),
+ for: .normal
+ )
+
+ authorizeAllPhotoButton.setTitle(
+ NSLocalizedString(
+ "albumlist.menu.authorizeAllPhoto.title",
+ tableName: "NohanaImagePicker",
+ bundle: nohanaImagePickerController.assetBundle,
+ comment: ""
+ ),
+ for: .normal
+ )
+ }
+
+ func isHiddenCell(_ isHidden: Bool) {
+ containerView.isHidden = isHidden
+ }
+
+ static func cellSize(_ nohanaImagePickerController: NohanaImagePickerController) -> CGSize {
+ let descriptionLabel = UILabel()
+ descriptionLabel.numberOfLines = 0
+ descriptionLabel.font = .systemFont(ofSize: 13.5)
+ descriptionLabel.text = NSLocalizedString("albumlist.menu.description", tableName: "NohanaImagePicker", bundle: nohanaImagePickerController.assetBundle, comment: "")
+ let maxSize: CGSize = .init(width: UIScreen.main.bounds.width - 28, height: .infinity)
+ let height: CGFloat = descriptionLabel.sizeThatFits(maxSize).height + 44 * 2 + 10 + 16 * 3
+ return .init(width: UIScreen.main.bounds.width, height: height)
+ }
+}
diff --git a/NohanaImagePicker/PhotoAuthorizationLimitedCell.xib b/NohanaImagePicker/PhotoAuthorizationLimitedCell.xib
new file mode 100644
index 0000000..0068e33
--- /dev/null
+++ b/NohanaImagePicker/PhotoAuthorizationLimitedCell.xib
@@ -0,0 +1,184 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 現在「選択した写真」のみ許可されています。
+設定画面の「写真」で「すべての写真」に✓を入れると、端末内のすべての写真から選べるようになります。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/NohanaImagePicker/RootViewController.swift b/NohanaImagePicker/RootViewController.swift
index 790c6a0..9f17ae4 100644
--- a/NohanaImagePicker/RootViewController.swift
+++ b/NohanaImagePicker/RootViewController.swift
@@ -215,6 +215,14 @@ class RootViewController: UIViewController {
}
})
}
+
+ @objc func didTapAddPhoto(_ notification: Notification) {
+ nohanaImagePickerController.delegate?.nohanaImagePickerDidTapAddPhotoButton?(nohanaImagePickerController)
+ }
+
+ @objc func didTapAuthorizeAllPhoto(_ notification: Notification) {
+ nohanaImagePickerController.delegate?.nohanaImagePickerDidTapAuthorizeAllPhotoButton?(nohanaImagePickerController)
+ }
// MARK: - IBAction
@IBAction func didTapDone(_ sender: AnyObject) {
diff --git a/NohanaImagePicker/de.lproj/NohanaImagePicker.strings b/NohanaImagePicker/de.lproj/NohanaImagePicker.strings
index 8b8b529..b51aede 100644
--- a/NohanaImagePicker/de.lproj/NohanaImagePicker.strings
+++ b/NohanaImagePicker/de.lproj/NohanaImagePicker.strings
@@ -19,6 +19,10 @@
"albumlist.empty.description" = "Nimm Fotos mit der Kamera App auf.";
"albumlist.empty.alert.button.ok" = "OK";
"albumlist.moment.title" = "Moment";
+"albumlist.menu.description" = "Derzeit sind nur \"ausgewählte Fotos\" erlaubt. \n
+Wenn Sie auf dem Einstellungsbildschirm unter „Fotos“ unter „Alle Fotos“ ✓ eingeben, können Sie aus allen Fotos im Terminal auswählen.";
+"albumlist.menu.addPhoto.title" = "Genehmigungsfoto hinzufügen";
+"albumlist.menu.authorizeAllPhoto.title" = "alle Fotos zulassen";
"toolbar.title.nolimit" = "Ausgewählte Fotos: %ld";
"toolbar.title.haslimit" = "Ausgewählte Fotos: %ld / %ld";
"action.title.select" = "Auswählen";
diff --git a/NohanaImagePicker/en.lproj/NohanaImagePicker.strings b/NohanaImagePicker/en.lproj/NohanaImagePicker.strings
index 8b4dbe4..073ffb5 100644
--- a/NohanaImagePicker/en.lproj/NohanaImagePicker.strings
+++ b/NohanaImagePicker/en.lproj/NohanaImagePicker.strings
@@ -19,7 +19,12 @@
"albumlist.empty.description" = "Take some photos with Camera app.";
"albumlist.empty.alert.button.ok" = "OK";
"albumlist.moment.title" = "Moment";
+"albumlist.menu.description" = "Currently only \"selected photos\" are allowed.\n
+If you put ✓ in \"All photos\" in \"Photos\" on the setting screen, you will be able to select from all the photos in the terminal.";
+"albumlist.menu.addPhoto.title" = "Add permission photo";
+"albumlist.menu.authorizeAllPhoto.title" = "Allow all photos";
"toolbar.title.nolimit" = "Selected Items: %ld";
"toolbar.title.haslimit" = "Selected Items: %ld / %ld";
"action.title.select" = "Select";
"action.title.deselect" = "Deselect";
+
diff --git a/NohanaImagePicker/ja.lproj/NohanaImagePicker.strings b/NohanaImagePicker/ja.lproj/NohanaImagePicker.strings
index 0595dde..88650d8 100644
--- a/NohanaImagePicker/ja.lproj/NohanaImagePicker.strings
+++ b/NohanaImagePicker/ja.lproj/NohanaImagePicker.strings
@@ -19,6 +19,10 @@
"albumlist.empty.description" = "カメラで写真を撮影しましょう";
"albumlist.empty.alert.button.ok" = "OK";
"albumlist.moment.title" = "日付から選択";
+"albumlist.menu.description" = "現在「選択した写真」のみ許可されています。\n
+設定画面の「写真」で「すべての写真」に✓を入れると、端末内のすべての写真から選べるようになります。";
+"albumlist.menu.addPhoto.title" = "許可写真を追加する";
+"albumlist.menu.authorizeAllPhoto.title" = "すべての写真を許可する";
"toolbar.title.nolimit" = "%ld枚選択中";
"toolbar.title.haslimit" = "%ld枚選択中(最大%ld枚)";
"action.title.select" = "選択する";
diff --git a/NohanaImagePicker/ru.lproj/NohanaImagePicker.strings b/NohanaImagePicker/ru.lproj/NohanaImagePicker.strings
index 1b6036d..fc03438 100644
--- a/NohanaImagePicker/ru.lproj/NohanaImagePicker.strings
+++ b/NohanaImagePicker/ru.lproj/NohanaImagePicker.strings
@@ -19,6 +19,10 @@
"albumlist.empty.description" = "Получить фото с камеры";
"albumlist.empty.alert.button.ok" = "ла́дно";
"albumlist.moment.title" = "Моменты";
+"albumlist.menu.description" = "В настоящее время разрешены только «избранные фотографии». \n
+Если вы поместите ✓ в «Все фотографии» в «Фотографии» на экране настроек, вы сможете выбрать из всех фотографий в терминале.";
+"albumlist.menu.addPhoto.title" = "добавить фото разрешения";
+"albumlist.menu.authorizeAllPhoto.title" = "разрешить все фото";
"toolbar.title.nolimit" = "Выбрано: %ld";
"toolbar.title.haslimit" = "Выбрано: %ld / %ld";
"action.title.select" = "Выбирать";