309 lines
13 KiB
Swift
309 lines
13 KiB
Swift
/*
|
|
* Copyright (C) 2016 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
|
|
import Photos
|
|
|
|
class AlbumListViewController: UITableViewController, EmptyIndicatable, ActivityIndicatable {
|
|
|
|
enum AlbumListViewControllerSectionType: Int {
|
|
case moment = 0
|
|
case albums
|
|
|
|
static func count() -> Int {
|
|
var count: Int = 0
|
|
for i in 0..<Int.max {
|
|
guard AlbumListViewControllerSectionType(rawValue: i) != nil else {
|
|
break
|
|
}
|
|
count = count + 1
|
|
}
|
|
return count
|
|
}
|
|
}
|
|
|
|
weak var nohanaImagePickerController: NohanaImagePickerController?
|
|
var photoKitAlbumList: PhotoKitAlbumList!
|
|
|
|
override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
if let nohanaImagePickerController = nohanaImagePickerController {
|
|
view.backgroundColor = nohanaImagePickerController.config.color.background ?? .white
|
|
title = nohanaImagePickerController.config.strings.albumListTitle ?? NSLocalizedString("albumlist.title", tableName: "NohanaImagePicker", bundle: nohanaImagePickerController.assetBundle, comment: "")
|
|
setUpToolbarItems()
|
|
navigationController?.setToolbarHidden(nohanaImagePickerController.toolbarHidden, animated: false)
|
|
}
|
|
setUpEmptyIndicator()
|
|
setUpActivityIndicator()
|
|
}
|
|
|
|
deinit {
|
|
NotificationCenter.default.removeObserver(self)
|
|
}
|
|
|
|
override func viewWillAppear(_ animated: Bool) {
|
|
super.viewWillAppear(animated)
|
|
if let nohanaImagePickerController = nohanaImagePickerController {
|
|
setToolbarTitle(nohanaImagePickerController)
|
|
}
|
|
if let indexPathForSelectedRow = tableView.indexPathForSelectedRow {
|
|
tableView.deselectRow(at: indexPathForSelectedRow, animated: true)
|
|
}
|
|
}
|
|
|
|
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
|
|
super.viewWillTransition(to: size, with: coordinator)
|
|
tableView.reloadData()
|
|
}
|
|
|
|
// MARK: - UITableViewDelegate
|
|
|
|
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
|
guard let sectionType = AlbumListViewControllerSectionType(rawValue: indexPath.section) else {
|
|
fatalError("Invalid section")
|
|
}
|
|
guard let nohanaImagePickerController = nohanaImagePickerController else {
|
|
return
|
|
}
|
|
switch sectionType {
|
|
case .moment:
|
|
nohanaImagePickerController.delegate?.nohanaImagePickerDidSelectMoment?(nohanaImagePickerController)
|
|
case .albums:
|
|
nohanaImagePickerController.delegate?.nohanaImagePicker?(nohanaImagePickerController, didSelectPhotoKitAssetList: photoKitAlbumList[indexPath.row].assetList)
|
|
}
|
|
}
|
|
|
|
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
|
|
guard let sectionType = AlbumListViewControllerSectionType(rawValue: indexPath.section) else {
|
|
fatalError("Invalid section")
|
|
}
|
|
switch sectionType {
|
|
case .moment:
|
|
return 52
|
|
case .albums:
|
|
return 82
|
|
}
|
|
}
|
|
|
|
// MARK: - UITableViewDataSource
|
|
|
|
override func numberOfSections(in tableView: UITableView) -> Int {
|
|
return AlbumListViewControllerSectionType.count()
|
|
}
|
|
|
|
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
|
if let emptyIndicator = emptyIndicator {
|
|
updateVisibilityOfEmptyIndicator(emptyIndicator)
|
|
}
|
|
if let activityIndicator = activityIndicator {
|
|
updateVisibilityOfActivityIndicator(activityIndicator)
|
|
}
|
|
|
|
guard let sectionType = AlbumListViewControllerSectionType(rawValue: section) else {
|
|
fatalError("Invalid section")
|
|
}
|
|
|
|
switch sectionType {
|
|
case .moment:
|
|
if let nohanaImagePickerController = nohanaImagePickerController {
|
|
return nohanaImagePickerController.shouldShowMoment ? 1 : 0
|
|
}
|
|
return 0
|
|
|
|
case .albums:
|
|
return photoKitAlbumList.count
|
|
}
|
|
}
|
|
|
|
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
|
guard let sectionType = AlbumListViewControllerSectionType(rawValue: indexPath.section) else {
|
|
fatalError("Invalid section")
|
|
}
|
|
|
|
switch sectionType {
|
|
case .moment:
|
|
guard let cell = tableView.dequeueReusableCell(withIdentifier: "MomentAlbumCell") as? MomentCell else {
|
|
fatalError("failed to dequeueReusableCellWithIdentifier(\"MomentAlbumCell\")")
|
|
}
|
|
if let nohanaImagePickerController = nohanaImagePickerController {
|
|
cell.config = nohanaImagePickerController.config
|
|
cell.titleLabel?.text = nohanaImagePickerController.config.strings.albumListMomentTitle ?? NSLocalizedString("albumlist.moment.title", tableName: "NohanaImagePicker", bundle: nohanaImagePickerController.assetBundle, comment: "")
|
|
}
|
|
return cell
|
|
case .albums:
|
|
guard let cell = tableView.dequeueReusableCell(withIdentifier: "AlbumCell") as? AlbumCell else {
|
|
fatalError("failed to dequeueReusableCellWithIdentifier(\"AlbumCell\")")
|
|
}
|
|
let albumList = photoKitAlbumList[indexPath.row]
|
|
cell.titleLabel.text = albumList.title
|
|
cell.tag = indexPath.row
|
|
let imageSize = CGSize(
|
|
width: cell.thumbnailImageView.frame.size.width * UIScreen.main.scale,
|
|
height: cell.thumbnailImageView.frame.size.width * UIScreen.main.scale
|
|
)
|
|
let albumCount = albumList.count
|
|
if albumCount > 0 {
|
|
let lastAsset = albumList[albumCount - 1]
|
|
lastAsset.image(targetSize: imageSize, handler: { (imageData) -> Void in
|
|
DispatchQueue.main.async(execute: { () -> Void in
|
|
if let imageData = imageData {
|
|
if cell.tag == indexPath.row {
|
|
cell.thumbnailImageView.image = imageData.image
|
|
}
|
|
}
|
|
})
|
|
})
|
|
} else {
|
|
cell.thumbnailImageView.image = nil
|
|
}
|
|
return cell
|
|
}
|
|
}
|
|
|
|
// MARK: - Storyboard
|
|
|
|
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
|
|
guard let sectionType = AlbumListViewControllerSectionType(rawValue: tableView.indexPathForSelectedRow!.section) else {
|
|
fatalError("Invalid section")
|
|
}
|
|
switch sectionType {
|
|
case .moment:
|
|
let momentViewController = segue.destination as! MomentViewController
|
|
momentViewController.nohanaImagePickerController = nohanaImagePickerController
|
|
momentViewController.momentAlbumList = PhotoKitAlbumList(
|
|
assetCollectionTypes: [.moment],
|
|
assetCollectionSubtypes: [.any],
|
|
mediaType: nohanaImagePickerController!.mediaType,
|
|
shouldShowEmptyAlbum: nohanaImagePickerController!.shouldShowEmptyAlbum,
|
|
handler: { () -> Void in
|
|
DispatchQueue.main.async(execute: { [weak momentViewController] in
|
|
momentViewController?.isLoading = false
|
|
momentViewController?.collectionView?.reloadData()
|
|
momentViewController?.isFirstAppearance = true
|
|
momentViewController?.scrollCollectionViewToInitialPosition()
|
|
})
|
|
})
|
|
case .albums:
|
|
let assetListViewController = segue.destination as! AssetListViewController
|
|
assetListViewController.photoKitAssetList = photoKitAlbumList[tableView.indexPathForSelectedRow!.row]
|
|
assetListViewController.nohanaImagePickerController = nohanaImagePickerController
|
|
}
|
|
}
|
|
|
|
// MARK: - IBAction
|
|
|
|
@IBAction func didPushCancel(_ sender: AnyObject) {
|
|
if let nohanaImagePickerController = nohanaImagePickerController {
|
|
nohanaImagePickerController.delegate?.nohanaImagePickerDidCancel(nohanaImagePickerController)
|
|
}
|
|
}
|
|
|
|
// MARK: - EmptyIndicatable
|
|
|
|
var emptyIndicator: UIView?
|
|
|
|
func setUpEmptyIndicator() {
|
|
let frame = CGRect(origin: CGPoint.zero, size: Size.screenRectWithoutAppBar(self).size)
|
|
guard let nohanaImagePickerController = nohanaImagePickerController else {
|
|
return
|
|
}
|
|
emptyIndicator = AlbumListEmptyIndicator(
|
|
message: nohanaImagePickerController.config.strings.albumListEmptyMessage ?? NSLocalizedString("albumlist.empty.message", tableName: "NohanaImagePicker", bundle: nohanaImagePickerController.assetBundle, comment: ""),
|
|
description: nohanaImagePickerController.config.strings.albumListEmptyDescription ?? NSLocalizedString("albumlist.empty.description", tableName: "NohanaImagePicker", bundle: nohanaImagePickerController.assetBundle, comment: ""),
|
|
frame: frame,
|
|
config: nohanaImagePickerController.config)
|
|
}
|
|
|
|
func isEmpty() -> Bool {
|
|
if isProgressing() {
|
|
return false
|
|
}
|
|
return photoKitAlbumList.count == 0
|
|
}
|
|
|
|
// MARK: - ActivityIndicatable
|
|
|
|
var activityIndicator: UIActivityIndicatorView?
|
|
var isLoading = true
|
|
|
|
func setUpActivityIndicator() {
|
|
activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: .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
|
|
}
|
|
}
|
|
|
|
extension UIViewController {
|
|
|
|
// MARK: - Toolbar
|
|
|
|
func setUpToolbarItems() {
|
|
let leftSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
|
|
let rightSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
|
|
|
|
let infoButton = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
|
|
infoButton.isEnabled = false
|
|
infoButton.setTitleTextAttributes([NSFontAttributeName: UIFont.systemFont(ofSize: 14), NSForegroundColorAttributeName: UIColor.black], for: UIControlState())
|
|
self.toolbarItems = [leftSpace, infoButton, rightSpace]
|
|
}
|
|
|
|
func setToolbarTitle(_ nohanaImagePickerController: NohanaImagePickerController) {
|
|
let count: Int? = toolbarItems?.count
|
|
guard count != nil && count! >= 2 else {
|
|
return
|
|
}
|
|
guard let infoButton = toolbarItems?[1] else {
|
|
return
|
|
}
|
|
if nohanaImagePickerController.maximumNumberOfSelection == 0 {
|
|
let title = String(format: nohanaImagePickerController.config.strings.toolbarTitleNoLimit ?? NSLocalizedString("toolbar.title.nolimit", tableName: "NohanaImagePicker", bundle: nohanaImagePickerController.assetBundle, comment: ""),
|
|
nohanaImagePickerController.pickedAssetList.count)
|
|
infoButton.title = title
|
|
} else {
|
|
let title = String(format: nohanaImagePickerController.config.strings.toolbarTitleHasLimit ?? NSLocalizedString("toolbar.title.haslimit", tableName: "NohanaImagePicker", bundle: nohanaImagePickerController.assetBundle, comment: ""),
|
|
nohanaImagePickerController.pickedAssetList.count,
|
|
nohanaImagePickerController.maximumNumberOfSelection)
|
|
infoButton.title = title
|
|
}
|
|
}
|
|
|
|
// MARK: - Notification
|
|
|
|
func addPickPhotoKitAssetNotificationObservers() {
|
|
NotificationCenter.default.addObserver(self, selector: #selector(AlbumListViewController.didPickPhotoKitAsset(_:)), name: NotificationInfo.Asset.PhotoKit.didPick, object: nil)
|
|
NotificationCenter.default.addObserver(self, selector: #selector(AlbumListViewController.didDropPhotoKitAsset(_:)), name: NotificationInfo.Asset.PhotoKit.didDrop, object: nil)
|
|
}
|
|
|
|
func didPickPhotoKitAsset(_ notification: Notification) {
|
|
guard let picker = notification.object as? NohanaImagePickerController else {
|
|
return
|
|
}
|
|
setToolbarTitle(picker)
|
|
}
|
|
|
|
func didDropPhotoKitAsset(_ notification: Notification) {
|
|
guard let picker = notification.object as? NohanaImagePickerController else {
|
|
return
|
|
}
|
|
setToolbarTitle(picker)
|
|
}
|
|
}
|