From 9abba06fca2ff2e5b0a0e5011c6d4324bb4da36f Mon Sep 17 00:00:00 2001 From: Timo Steinwender Date: Mon, 27 Feb 2017 17:17:41 +0100 Subject: [PATCH 1/3] fixed the following things: 1. added property to disable the file sharing button 2. canRemoveFiles will remove the removeButton in the preview section 3. disabled userInteraction for the check button to handle the selection only over the cell 4. if allowMultipleSelection is disabled: only select one item to avoid misunderstanding --- .../FileExplorer/ActionsViewController.swift | 21 ++++++++++++------- .../FileExplorer/CheckmarkButton.swift | 1 + FileExplorer/FileExplorer/Configuration.swift | 1 + .../DirectoryContentViewController.swift | 18 ++++++++++++++++ .../DirectoryContentViewModel.swift | 14 ++++++++++--- .../FileExplorerViewController.swift | 6 +++++- .../FileItemPresentationCoordinator.swift | 6 ++++-- .../ItemPresentationCoordinator.swift | 4 ++-- 8 files changed, 56 insertions(+), 15 deletions(-) diff --git a/FileExplorer/FileExplorer/ActionsViewController.swift b/FileExplorer/FileExplorer/ActionsViewController.swift index aa5e46e..2a06185 100644 --- a/FileExplorer/FileExplorer/ActionsViewController.swift +++ b/FileExplorer/FileExplorer/ActionsViewController.swift @@ -35,8 +35,9 @@ final class ActionsViewController: UIViewController { private let toolbar = UIToolbar() private let contentViewController: UIViewController - - init(contentViewController: UIViewController) { + fileprivate let configuration: Configuration + init(configuration: Configuration, contentViewController: UIViewController) { + self.configuration = configuration self.contentViewController = contentViewController super.init(nibName: nil, bundle: nil) } @@ -57,11 +58,17 @@ final class ActionsViewController: UIViewController { toolbar.translatesAutoresizingMaskIntoConstraints = false toolbar.sizeToFit() toolbar.pinToBottom(of: view) - toolbar.items = [ - UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(handleShareButtonTap)), - UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil), - UIBarButtonItem(barButtonSystemItem: .trash, target: self, action: #selector(handleTrashButtonTap)) - ] + //always add the flexibleSpace + toolbar.items = [UIBarButtonItem]() + toolbar.items?.append(UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil)) + if configuration.actionsConfiguration.canShareFiles + { + toolbar.items?.insert(UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(handleShareButtonTap)), at: 0) + } + if configuration.actionsConfiguration.canRemoveFiles + { + toolbar.items?.append(UIBarButtonItem(barButtonSystemItem: .trash, target: self, action: #selector(handleTrashButtonTap))) + } addContentChildViewController(contentViewController, insets: UIEdgeInsets(top: 0, left: 0, bottom: toolbar.bounds.height, right: 0)) navigationItem.title = contentViewController.navigationItem.title diff --git a/FileExplorer/FileExplorer/CheckmarkButton.swift b/FileExplorer/FileExplorer/CheckmarkButton.swift index 64cd7b7..2522149 100644 --- a/FileExplorer/FileExplorer/CheckmarkButton.swift +++ b/FileExplorer/FileExplorer/CheckmarkButton.swift @@ -51,6 +51,7 @@ final class CheckmarkButton: UIButton { borderColor = ColorPallete.gray isSelected = false addTarget(self, action: #selector(handleTouchUpInside), for: .touchUpInside) + isUserInteractionEnabled = false } required init?(coder aDecoder: NSCoder) { diff --git a/FileExplorer/FileExplorer/Configuration.swift b/FileExplorer/FileExplorer/Configuration.swift index 4d94b07..5054fe6 100644 --- a/FileExplorer/FileExplorer/Configuration.swift +++ b/FileExplorer/FileExplorer/Configuration.swift @@ -31,6 +31,7 @@ struct Configuration { } struct ActionsConfiguration { + var canShareFiles: Bool = false var canRemoveFiles: Bool = false var canRemoveDirectories: Bool = false var canChooseFiles: Bool = false diff --git a/FileExplorer/FileExplorer/DirectoryContentViewController.swift b/FileExplorer/FileExplorer/DirectoryContentViewController.swift index 30fe08c..c6c4fb6 100644 --- a/FileExplorer/FileExplorer/DirectoryContentViewController.swift +++ b/FileExplorer/FileExplorer/DirectoryContentViewController.swift @@ -111,6 +111,24 @@ final class DirectoryContentViewController: UICollectionViewController { activeNavigationItemTitle = viewModel.title view.isUserInteractionEnabled = viewModel.isUserInteractionEnabled setEditing(viewModel.isEditing, animated: true) + //get the selection states from the view model and syncronize them + let selectedCellPaths = viewModel.indexPathsOfSelectedCells + for i in 0...viewModel.numberOfItems(inSection: 0) + { + guard let collectionView = collectionView else { return } + let searchIndexPath = IndexPath(item: i, section: 0) + var selectedIndexPath = selectedCellPaths.index(of: searchIndexPath) + var selected = selectedIndexPath != nil ? true : false + if selected + { + collectionView.selectItem(at: searchIndexPath, animated: true, scrollPosition: UICollectionViewScrollPosition.left) + } + else + { + collectionView.deselectItem(at: searchIndexPath, animated: false) + } + } + } override func setEditing(_ editing: Bool, animated: Bool) { diff --git a/FileExplorer/FileExplorer/DirectoryContentViewModel.swift b/FileExplorer/FileExplorer/DirectoryContentViewModel.swift index 627d913..a02e4f3 100644 --- a/FileExplorer/FileExplorer/DirectoryContentViewModel.swift +++ b/FileExplorer/FileExplorer/DirectoryContentViewModel.swift @@ -148,9 +148,10 @@ final class DirectoryContentViewModel { } let numberOfSelectedItemsIsAllowed = configuration.actionsConfiguration.allowsMultipleSelection ? selectedItems.count > 0 : selectedItems.count == 1 + return !fileService.isDeletionInProgress && selectedItemsAreAllowedToBeSelected && numberOfSelectedItemsIsAllowed } - + var selectActionTitle: String { return NSLocalizedString("Choose", comment: "") } @@ -162,7 +163,7 @@ final class DirectoryContentViewModel { private let configuration: Configuration private let fileSpecifications: FileSpecifications private let fileService: FileService - + init(item: LoadedDirectoryItem, fileSpecifications: FileSpecifications, configuration: Configuration, fileService: FileService = LocalStorageFileService()) { self.url = item.url self.fileSpecifications = fileSpecifications @@ -181,7 +182,14 @@ final class DirectoryContentViewModel { func select(at indexPath: IndexPath) { let item = self.item(for: indexPath) if isEditing { - selectedItems.append(item) + if(configuration.actionsConfiguration.allowsMultipleSelection) + { + selectedItems.append(item) + } + else{ + selectedItems.removeAll() + selectedItems.append(item) + } } else { delegate?.directoryViewModel(self, didSelectItem: item) } diff --git a/FileExplorer/FileExplorer/FileExplorerViewController.swift b/FileExplorer/FileExplorer/FileExplorerViewController.swift index 13b3691..9f21b83 100644 --- a/FileExplorer/FileExplorer/FileExplorerViewController.swift +++ b/FileExplorer/FileExplorer/FileExplorerViewController.swift @@ -48,6 +48,9 @@ public final class FileExplorerViewController: UIViewController { /// The URL of directory which is initialy presented by file explorer view controller. public var initialDirectoryURL: URL = URL.documentDirectory + /// A Boolean value indicating whether the user is allowed to remove files. + public var canShareFiles: Bool = true + /// A Boolean value indicating whether the user is allowed to remove files. public var canRemoveFiles: Bool = true @@ -113,7 +116,8 @@ public final class FileExplorerViewController: UIViewController { super.viewWillAppear(animated) let fileSpecifications = FileSpecifications(providers: fileSpecificationProviders) - let actionsConfiguration = ActionsConfiguration(canRemoveFiles: canRemoveFiles, + let actionsConfiguration = ActionsConfiguration(canShareFiles: canShareFiles, + canRemoveFiles: canRemoveFiles, canRemoveDirectories: canRemoveDirectories, canChooseFiles: canChooseFiles, canChooseDirectories: canChooseDirectories, diff --git a/FileExplorer/FileExplorer/FileItemPresentationCoordinator.swift b/FileExplorer/FileExplorer/FileItemPresentationCoordinator.swift index d4721bc..da57725 100644 --- a/FileExplorer/FileExplorer/FileItemPresentationCoordinator.swift +++ b/FileExplorer/FileExplorer/FileItemPresentationCoordinator.swift @@ -32,9 +32,11 @@ final class FileItemPresentationCoordinator { fileprivate weak var navigationController: UINavigationController? fileprivate let fileService: FileService fileprivate let fileSpecifications: FileSpecifications + fileprivate let configuration: Configuration fileprivate let item: Item - init(navigationController: UINavigationController, item: Item, fileSpecifications: FileSpecifications, fileService: FileService = LocalStorageFileService()) { + init(configuration: Configuration, navigationController: UINavigationController, item: Item, fileSpecifications: FileSpecifications, fileService: FileService = LocalStorageFileService()) { + self.configuration = configuration self.navigationController = navigationController self.item = item self.fileSpecifications = fileSpecifications @@ -69,7 +71,7 @@ final class FileItemPresentationCoordinator { private func makePresentingViewController(item: Item, builder: @escaping (LoadedItem) -> UIViewController) -> UIViewController { let viewController = LoadingViewController.make(item: item) { [weak self] loadedItem in let contentViewController = builder(loadedItem) - let actionsViewController = ActionsViewController(contentViewController: contentViewController) + let actionsViewController = ActionsViewController(configuration: self!.configuration, contentViewController: contentViewController) actionsViewController.delegate = self return actionsViewController } diff --git a/FileExplorer/FileExplorer/ItemPresentationCoordinator.swift b/FileExplorer/FileExplorer/ItemPresentationCoordinator.swift index 2750dc2..c08e0db 100644 --- a/FileExplorer/FileExplorer/ItemPresentationCoordinator.swift +++ b/FileExplorer/FileExplorer/ItemPresentationCoordinator.swift @@ -51,7 +51,7 @@ final class ItemPresentationCoordinator { switch item.type { case .file: - let coordinator = FileItemPresentationCoordinator(navigationController: navigationController, item: item, fileSpecifications: fileSpecifications) + let coordinator = FileItemPresentationCoordinator(configuration: configuration, navigationController: navigationController, item: item, fileSpecifications: fileSpecifications) coordinator.start(animated) childCoordinators.append(coordinator) case .directory: @@ -75,7 +75,7 @@ extension ItemPresentationCoordinator: DirectoryItemPresentationCoordinatorDeleg func directoryItemPresentationCoordinator(_ coordinator: DirectoryItemPresentationCoordinator, didSelectItemDetails item: Item) { guard let navigationController = navigationController else { fatalError() } - let coordinator = FileItemPresentationCoordinator(navigationController: navigationController, item: item, fileSpecifications: fileSpecifications) + let coordinator = FileItemPresentationCoordinator(configuration: configuration, navigationController: navigationController, item: item, fileSpecifications: fileSpecifications) childCoordinators.append(coordinator) coordinator.startDetailsPreview(true) } From 70d33772e80af37941479ede52e0284ef9d0f630 Mon Sep 17 00:00:00 2001 From: Timo Steinwender Date: Mon, 27 Feb 2017 17:20:30 +0100 Subject: [PATCH 2/3] Revert "fixed the following things:" This reverts commit 9abba06fca2ff2e5b0a0e5011c6d4324bb4da36f. --- .../FileExplorer/ActionsViewController.swift | 21 +++++++------------ .../FileExplorer/CheckmarkButton.swift | 1 - FileExplorer/FileExplorer/Configuration.swift | 1 - .../DirectoryContentViewController.swift | 18 ---------------- .../DirectoryContentViewModel.swift | 14 +++---------- .../FileExplorerViewController.swift | 6 +----- .../FileItemPresentationCoordinator.swift | 6 ++---- .../ItemPresentationCoordinator.swift | 4 ++-- 8 files changed, 15 insertions(+), 56 deletions(-) diff --git a/FileExplorer/FileExplorer/ActionsViewController.swift b/FileExplorer/FileExplorer/ActionsViewController.swift index 2a06185..aa5e46e 100644 --- a/FileExplorer/FileExplorer/ActionsViewController.swift +++ b/FileExplorer/FileExplorer/ActionsViewController.swift @@ -35,9 +35,8 @@ final class ActionsViewController: UIViewController { private let toolbar = UIToolbar() private let contentViewController: UIViewController - fileprivate let configuration: Configuration - init(configuration: Configuration, contentViewController: UIViewController) { - self.configuration = configuration + + init(contentViewController: UIViewController) { self.contentViewController = contentViewController super.init(nibName: nil, bundle: nil) } @@ -58,17 +57,11 @@ final class ActionsViewController: UIViewController { toolbar.translatesAutoresizingMaskIntoConstraints = false toolbar.sizeToFit() toolbar.pinToBottom(of: view) - //always add the flexibleSpace - toolbar.items = [UIBarButtonItem]() - toolbar.items?.append(UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil)) - if configuration.actionsConfiguration.canShareFiles - { - toolbar.items?.insert(UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(handleShareButtonTap)), at: 0) - } - if configuration.actionsConfiguration.canRemoveFiles - { - toolbar.items?.append(UIBarButtonItem(barButtonSystemItem: .trash, target: self, action: #selector(handleTrashButtonTap))) - } + toolbar.items = [ + UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(handleShareButtonTap)), + UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil), + UIBarButtonItem(barButtonSystemItem: .trash, target: self, action: #selector(handleTrashButtonTap)) + ] addContentChildViewController(contentViewController, insets: UIEdgeInsets(top: 0, left: 0, bottom: toolbar.bounds.height, right: 0)) navigationItem.title = contentViewController.navigationItem.title diff --git a/FileExplorer/FileExplorer/CheckmarkButton.swift b/FileExplorer/FileExplorer/CheckmarkButton.swift index 2522149..64cd7b7 100644 --- a/FileExplorer/FileExplorer/CheckmarkButton.swift +++ b/FileExplorer/FileExplorer/CheckmarkButton.swift @@ -51,7 +51,6 @@ final class CheckmarkButton: UIButton { borderColor = ColorPallete.gray isSelected = false addTarget(self, action: #selector(handleTouchUpInside), for: .touchUpInside) - isUserInteractionEnabled = false } required init?(coder aDecoder: NSCoder) { diff --git a/FileExplorer/FileExplorer/Configuration.swift b/FileExplorer/FileExplorer/Configuration.swift index 5054fe6..4d94b07 100644 --- a/FileExplorer/FileExplorer/Configuration.swift +++ b/FileExplorer/FileExplorer/Configuration.swift @@ -31,7 +31,6 @@ struct Configuration { } struct ActionsConfiguration { - var canShareFiles: Bool = false var canRemoveFiles: Bool = false var canRemoveDirectories: Bool = false var canChooseFiles: Bool = false diff --git a/FileExplorer/FileExplorer/DirectoryContentViewController.swift b/FileExplorer/FileExplorer/DirectoryContentViewController.swift index c6c4fb6..30fe08c 100644 --- a/FileExplorer/FileExplorer/DirectoryContentViewController.swift +++ b/FileExplorer/FileExplorer/DirectoryContentViewController.swift @@ -111,24 +111,6 @@ final class DirectoryContentViewController: UICollectionViewController { activeNavigationItemTitle = viewModel.title view.isUserInteractionEnabled = viewModel.isUserInteractionEnabled setEditing(viewModel.isEditing, animated: true) - //get the selection states from the view model and syncronize them - let selectedCellPaths = viewModel.indexPathsOfSelectedCells - for i in 0...viewModel.numberOfItems(inSection: 0) - { - guard let collectionView = collectionView else { return } - let searchIndexPath = IndexPath(item: i, section: 0) - var selectedIndexPath = selectedCellPaths.index(of: searchIndexPath) - var selected = selectedIndexPath != nil ? true : false - if selected - { - collectionView.selectItem(at: searchIndexPath, animated: true, scrollPosition: UICollectionViewScrollPosition.left) - } - else - { - collectionView.deselectItem(at: searchIndexPath, animated: false) - } - } - } override func setEditing(_ editing: Bool, animated: Bool) { diff --git a/FileExplorer/FileExplorer/DirectoryContentViewModel.swift b/FileExplorer/FileExplorer/DirectoryContentViewModel.swift index a02e4f3..627d913 100644 --- a/FileExplorer/FileExplorer/DirectoryContentViewModel.swift +++ b/FileExplorer/FileExplorer/DirectoryContentViewModel.swift @@ -148,10 +148,9 @@ final class DirectoryContentViewModel { } let numberOfSelectedItemsIsAllowed = configuration.actionsConfiguration.allowsMultipleSelection ? selectedItems.count > 0 : selectedItems.count == 1 - return !fileService.isDeletionInProgress && selectedItemsAreAllowedToBeSelected && numberOfSelectedItemsIsAllowed } - + var selectActionTitle: String { return NSLocalizedString("Choose", comment: "") } @@ -163,7 +162,7 @@ final class DirectoryContentViewModel { private let configuration: Configuration private let fileSpecifications: FileSpecifications private let fileService: FileService - + init(item: LoadedDirectoryItem, fileSpecifications: FileSpecifications, configuration: Configuration, fileService: FileService = LocalStorageFileService()) { self.url = item.url self.fileSpecifications = fileSpecifications @@ -182,14 +181,7 @@ final class DirectoryContentViewModel { func select(at indexPath: IndexPath) { let item = self.item(for: indexPath) if isEditing { - if(configuration.actionsConfiguration.allowsMultipleSelection) - { - selectedItems.append(item) - } - else{ - selectedItems.removeAll() - selectedItems.append(item) - } + selectedItems.append(item) } else { delegate?.directoryViewModel(self, didSelectItem: item) } diff --git a/FileExplorer/FileExplorer/FileExplorerViewController.swift b/FileExplorer/FileExplorer/FileExplorerViewController.swift index 9f21b83..13b3691 100644 --- a/FileExplorer/FileExplorer/FileExplorerViewController.swift +++ b/FileExplorer/FileExplorer/FileExplorerViewController.swift @@ -48,9 +48,6 @@ public final class FileExplorerViewController: UIViewController { /// The URL of directory which is initialy presented by file explorer view controller. public var initialDirectoryURL: URL = URL.documentDirectory - /// A Boolean value indicating whether the user is allowed to remove files. - public var canShareFiles: Bool = true - /// A Boolean value indicating whether the user is allowed to remove files. public var canRemoveFiles: Bool = true @@ -116,8 +113,7 @@ public final class FileExplorerViewController: UIViewController { super.viewWillAppear(animated) let fileSpecifications = FileSpecifications(providers: fileSpecificationProviders) - let actionsConfiguration = ActionsConfiguration(canShareFiles: canShareFiles, - canRemoveFiles: canRemoveFiles, + let actionsConfiguration = ActionsConfiguration(canRemoveFiles: canRemoveFiles, canRemoveDirectories: canRemoveDirectories, canChooseFiles: canChooseFiles, canChooseDirectories: canChooseDirectories, diff --git a/FileExplorer/FileExplorer/FileItemPresentationCoordinator.swift b/FileExplorer/FileExplorer/FileItemPresentationCoordinator.swift index da57725..d4721bc 100644 --- a/FileExplorer/FileExplorer/FileItemPresentationCoordinator.swift +++ b/FileExplorer/FileExplorer/FileItemPresentationCoordinator.swift @@ -32,11 +32,9 @@ final class FileItemPresentationCoordinator { fileprivate weak var navigationController: UINavigationController? fileprivate let fileService: FileService fileprivate let fileSpecifications: FileSpecifications - fileprivate let configuration: Configuration fileprivate let item: Item - init(configuration: Configuration, navigationController: UINavigationController, item: Item, fileSpecifications: FileSpecifications, fileService: FileService = LocalStorageFileService()) { - self.configuration = configuration + init(navigationController: UINavigationController, item: Item, fileSpecifications: FileSpecifications, fileService: FileService = LocalStorageFileService()) { self.navigationController = navigationController self.item = item self.fileSpecifications = fileSpecifications @@ -71,7 +69,7 @@ final class FileItemPresentationCoordinator { private func makePresentingViewController(item: Item, builder: @escaping (LoadedItem) -> UIViewController) -> UIViewController { let viewController = LoadingViewController.make(item: item) { [weak self] loadedItem in let contentViewController = builder(loadedItem) - let actionsViewController = ActionsViewController(configuration: self!.configuration, contentViewController: contentViewController) + let actionsViewController = ActionsViewController(contentViewController: contentViewController) actionsViewController.delegate = self return actionsViewController } diff --git a/FileExplorer/FileExplorer/ItemPresentationCoordinator.swift b/FileExplorer/FileExplorer/ItemPresentationCoordinator.swift index c08e0db..2750dc2 100644 --- a/FileExplorer/FileExplorer/ItemPresentationCoordinator.swift +++ b/FileExplorer/FileExplorer/ItemPresentationCoordinator.swift @@ -51,7 +51,7 @@ final class ItemPresentationCoordinator { switch item.type { case .file: - let coordinator = FileItemPresentationCoordinator(configuration: configuration, navigationController: navigationController, item: item, fileSpecifications: fileSpecifications) + let coordinator = FileItemPresentationCoordinator(navigationController: navigationController, item: item, fileSpecifications: fileSpecifications) coordinator.start(animated) childCoordinators.append(coordinator) case .directory: @@ -75,7 +75,7 @@ extension ItemPresentationCoordinator: DirectoryItemPresentationCoordinatorDeleg func directoryItemPresentationCoordinator(_ coordinator: DirectoryItemPresentationCoordinator, didSelectItemDetails item: Item) { guard let navigationController = navigationController else { fatalError() } - let coordinator = FileItemPresentationCoordinator(configuration: configuration, navigationController: navigationController, item: item, fileSpecifications: fileSpecifications) + let coordinator = FileItemPresentationCoordinator(navigationController: navigationController, item: item, fileSpecifications: fileSpecifications) childCoordinators.append(coordinator) coordinator.startDetailsPreview(true) } From 11efbf28e1262a828d5af496248c26c48c88b40f Mon Sep 17 00:00:00 2001 From: Timo Steinwender Date: Mon, 27 Feb 2017 17:22:56 +0100 Subject: [PATCH 3/3] fixed the following things: 1. added property to disable the file sharing button 2. canRemoveFiles will remove the removeButton in the preview section 3. disabled userInteraction for the check button to handle the selection only over the cell 4. if allowMultipleSelection is disabled: only select one item to avoid misunderstanding --- .../FileExplorer/ActionsViewController.swift | 21 ++++++++++++------- .../FileExplorer/CheckmarkButton.swift | 1 + FileExplorer/FileExplorer/Configuration.swift | 1 + .../DirectoryContentViewController.swift | 18 ++++++++++++++++ .../DirectoryContentViewModel.swift | 14 ++++++++++--- .../FileExplorerViewController.swift | 6 +++++- .../FileItemPresentationCoordinator.swift | 6 ++++-- .../ItemPresentationCoordinator.swift | 4 ++-- 8 files changed, 56 insertions(+), 15 deletions(-) diff --git a/FileExplorer/FileExplorer/ActionsViewController.swift b/FileExplorer/FileExplorer/ActionsViewController.swift index aa5e46e..2a06185 100644 --- a/FileExplorer/FileExplorer/ActionsViewController.swift +++ b/FileExplorer/FileExplorer/ActionsViewController.swift @@ -35,8 +35,9 @@ final class ActionsViewController: UIViewController { private let toolbar = UIToolbar() private let contentViewController: UIViewController - - init(contentViewController: UIViewController) { + fileprivate let configuration: Configuration + init(configuration: Configuration, contentViewController: UIViewController) { + self.configuration = configuration self.contentViewController = contentViewController super.init(nibName: nil, bundle: nil) } @@ -57,11 +58,17 @@ final class ActionsViewController: UIViewController { toolbar.translatesAutoresizingMaskIntoConstraints = false toolbar.sizeToFit() toolbar.pinToBottom(of: view) - toolbar.items = [ - UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(handleShareButtonTap)), - UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil), - UIBarButtonItem(barButtonSystemItem: .trash, target: self, action: #selector(handleTrashButtonTap)) - ] + //always add the flexibleSpace + toolbar.items = [UIBarButtonItem]() + toolbar.items?.append(UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil)) + if configuration.actionsConfiguration.canShareFiles + { + toolbar.items?.insert(UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(handleShareButtonTap)), at: 0) + } + if configuration.actionsConfiguration.canRemoveFiles + { + toolbar.items?.append(UIBarButtonItem(barButtonSystemItem: .trash, target: self, action: #selector(handleTrashButtonTap))) + } addContentChildViewController(contentViewController, insets: UIEdgeInsets(top: 0, left: 0, bottom: toolbar.bounds.height, right: 0)) navigationItem.title = contentViewController.navigationItem.title diff --git a/FileExplorer/FileExplorer/CheckmarkButton.swift b/FileExplorer/FileExplorer/CheckmarkButton.swift index 64cd7b7..2522149 100644 --- a/FileExplorer/FileExplorer/CheckmarkButton.swift +++ b/FileExplorer/FileExplorer/CheckmarkButton.swift @@ -51,6 +51,7 @@ final class CheckmarkButton: UIButton { borderColor = ColorPallete.gray isSelected = false addTarget(self, action: #selector(handleTouchUpInside), for: .touchUpInside) + isUserInteractionEnabled = false } required init?(coder aDecoder: NSCoder) { diff --git a/FileExplorer/FileExplorer/Configuration.swift b/FileExplorer/FileExplorer/Configuration.swift index 4d94b07..5054fe6 100644 --- a/FileExplorer/FileExplorer/Configuration.swift +++ b/FileExplorer/FileExplorer/Configuration.swift @@ -31,6 +31,7 @@ struct Configuration { } struct ActionsConfiguration { + var canShareFiles: Bool = false var canRemoveFiles: Bool = false var canRemoveDirectories: Bool = false var canChooseFiles: Bool = false diff --git a/FileExplorer/FileExplorer/DirectoryContentViewController.swift b/FileExplorer/FileExplorer/DirectoryContentViewController.swift index 30fe08c..c6c4fb6 100644 --- a/FileExplorer/FileExplorer/DirectoryContentViewController.swift +++ b/FileExplorer/FileExplorer/DirectoryContentViewController.swift @@ -111,6 +111,24 @@ final class DirectoryContentViewController: UICollectionViewController { activeNavigationItemTitle = viewModel.title view.isUserInteractionEnabled = viewModel.isUserInteractionEnabled setEditing(viewModel.isEditing, animated: true) + //get the selection states from the view model and syncronize them + let selectedCellPaths = viewModel.indexPathsOfSelectedCells + for i in 0...viewModel.numberOfItems(inSection: 0) + { + guard let collectionView = collectionView else { return } + let searchIndexPath = IndexPath(item: i, section: 0) + var selectedIndexPath = selectedCellPaths.index(of: searchIndexPath) + var selected = selectedIndexPath != nil ? true : false + if selected + { + collectionView.selectItem(at: searchIndexPath, animated: true, scrollPosition: UICollectionViewScrollPosition.left) + } + else + { + collectionView.deselectItem(at: searchIndexPath, animated: false) + } + } + } override func setEditing(_ editing: Bool, animated: Bool) { diff --git a/FileExplorer/FileExplorer/DirectoryContentViewModel.swift b/FileExplorer/FileExplorer/DirectoryContentViewModel.swift index 627d913..a02e4f3 100644 --- a/FileExplorer/FileExplorer/DirectoryContentViewModel.swift +++ b/FileExplorer/FileExplorer/DirectoryContentViewModel.swift @@ -148,9 +148,10 @@ final class DirectoryContentViewModel { } let numberOfSelectedItemsIsAllowed = configuration.actionsConfiguration.allowsMultipleSelection ? selectedItems.count > 0 : selectedItems.count == 1 + return !fileService.isDeletionInProgress && selectedItemsAreAllowedToBeSelected && numberOfSelectedItemsIsAllowed } - + var selectActionTitle: String { return NSLocalizedString("Choose", comment: "") } @@ -162,7 +163,7 @@ final class DirectoryContentViewModel { private let configuration: Configuration private let fileSpecifications: FileSpecifications private let fileService: FileService - + init(item: LoadedDirectoryItem, fileSpecifications: FileSpecifications, configuration: Configuration, fileService: FileService = LocalStorageFileService()) { self.url = item.url self.fileSpecifications = fileSpecifications @@ -181,7 +182,14 @@ final class DirectoryContentViewModel { func select(at indexPath: IndexPath) { let item = self.item(for: indexPath) if isEditing { - selectedItems.append(item) + if(configuration.actionsConfiguration.allowsMultipleSelection) + { + selectedItems.append(item) + } + else{ + selectedItems.removeAll() + selectedItems.append(item) + } } else { delegate?.directoryViewModel(self, didSelectItem: item) } diff --git a/FileExplorer/FileExplorer/FileExplorerViewController.swift b/FileExplorer/FileExplorer/FileExplorerViewController.swift index 13b3691..9f21b83 100644 --- a/FileExplorer/FileExplorer/FileExplorerViewController.swift +++ b/FileExplorer/FileExplorer/FileExplorerViewController.swift @@ -48,6 +48,9 @@ public final class FileExplorerViewController: UIViewController { /// The URL of directory which is initialy presented by file explorer view controller. public var initialDirectoryURL: URL = URL.documentDirectory + /// A Boolean value indicating whether the user is allowed to remove files. + public var canShareFiles: Bool = true + /// A Boolean value indicating whether the user is allowed to remove files. public var canRemoveFiles: Bool = true @@ -113,7 +116,8 @@ public final class FileExplorerViewController: UIViewController { super.viewWillAppear(animated) let fileSpecifications = FileSpecifications(providers: fileSpecificationProviders) - let actionsConfiguration = ActionsConfiguration(canRemoveFiles: canRemoveFiles, + let actionsConfiguration = ActionsConfiguration(canShareFiles: canShareFiles, + canRemoveFiles: canRemoveFiles, canRemoveDirectories: canRemoveDirectories, canChooseFiles: canChooseFiles, canChooseDirectories: canChooseDirectories, diff --git a/FileExplorer/FileExplorer/FileItemPresentationCoordinator.swift b/FileExplorer/FileExplorer/FileItemPresentationCoordinator.swift index d4721bc..da57725 100644 --- a/FileExplorer/FileExplorer/FileItemPresentationCoordinator.swift +++ b/FileExplorer/FileExplorer/FileItemPresentationCoordinator.swift @@ -32,9 +32,11 @@ final class FileItemPresentationCoordinator { fileprivate weak var navigationController: UINavigationController? fileprivate let fileService: FileService fileprivate let fileSpecifications: FileSpecifications + fileprivate let configuration: Configuration fileprivate let item: Item - init(navigationController: UINavigationController, item: Item, fileSpecifications: FileSpecifications, fileService: FileService = LocalStorageFileService()) { + init(configuration: Configuration, navigationController: UINavigationController, item: Item, fileSpecifications: FileSpecifications, fileService: FileService = LocalStorageFileService()) { + self.configuration = configuration self.navigationController = navigationController self.item = item self.fileSpecifications = fileSpecifications @@ -69,7 +71,7 @@ final class FileItemPresentationCoordinator { private func makePresentingViewController(item: Item, builder: @escaping (LoadedItem) -> UIViewController) -> UIViewController { let viewController = LoadingViewController.make(item: item) { [weak self] loadedItem in let contentViewController = builder(loadedItem) - let actionsViewController = ActionsViewController(contentViewController: contentViewController) + let actionsViewController = ActionsViewController(configuration: self!.configuration, contentViewController: contentViewController) actionsViewController.delegate = self return actionsViewController } diff --git a/FileExplorer/FileExplorer/ItemPresentationCoordinator.swift b/FileExplorer/FileExplorer/ItemPresentationCoordinator.swift index 2750dc2..c08e0db 100644 --- a/FileExplorer/FileExplorer/ItemPresentationCoordinator.swift +++ b/FileExplorer/FileExplorer/ItemPresentationCoordinator.swift @@ -51,7 +51,7 @@ final class ItemPresentationCoordinator { switch item.type { case .file: - let coordinator = FileItemPresentationCoordinator(navigationController: navigationController, item: item, fileSpecifications: fileSpecifications) + let coordinator = FileItemPresentationCoordinator(configuration: configuration, navigationController: navigationController, item: item, fileSpecifications: fileSpecifications) coordinator.start(animated) childCoordinators.append(coordinator) case .directory: @@ -75,7 +75,7 @@ extension ItemPresentationCoordinator: DirectoryItemPresentationCoordinatorDeleg func directoryItemPresentationCoordinator(_ coordinator: DirectoryItemPresentationCoordinator, didSelectItemDetails item: Item) { guard let navigationController = navigationController else { fatalError() } - let coordinator = FileItemPresentationCoordinator(navigationController: navigationController, item: item, fileSpecifications: fileSpecifications) + let coordinator = FileItemPresentationCoordinator(configuration: configuration, navigationController: navigationController, item: item, fileSpecifications: fileSpecifications) childCoordinators.append(coordinator) coordinator.startDetailsPreview(true) }