diff --git a/ownCloud/Client/Actions/Action.swift b/ownCloud/Client/Actions/Action.swift index 4f90c1f9e..3d09fbc3d 100644 --- a/ownCloud/Client/Actions/Action.swift +++ b/ownCloud/Client/Actions/Action.swift @@ -87,14 +87,16 @@ class ActionContext: OCExtensionContext { weak var core: OCCore? weak var query: OCQuery? var items: [OCItem] + weak var sender: AnyObject? // MARK: - Init & Deinit. - init(viewController: UIViewController, core: OCCore, query: OCQuery? = nil, items: [OCItem], location: OCExtensionLocation, requirements: [String : Any]? = nil, preferences: [String : Any]? = nil) { + init(viewController: UIViewController, core: OCCore, query: OCQuery? = nil, items: [OCItem], location: OCExtensionLocation, sender: AnyObject? = nil, requirements: [String : Any]? = nil, preferences: [String : Any]? = nil) { self.items = items super.init() self.viewController = viewController + self.sender = sender self.core = core self.location = location diff --git a/ownCloud/Client/Actions/Actions+Extensions/OpenInAction.swift b/ownCloud/Client/Actions/Actions+Extensions/OpenInAction.swift index 1da5190c9..77a841c8c 100644 --- a/ownCloud/Client/Actions/Actions+Extensions/OpenInAction.swift +++ b/ownCloud/Client/Actions/Actions+Extensions/OpenInAction.swift @@ -54,7 +54,6 @@ class OpenInAction: Action { hostViewController?.present(alertController, animated: true) } else { guard let files = files, files.count > 0, let viewController = hostViewController else { return } - // UIDocumentInteractionController can only be used with a single file if files.count == 1 { if let fileURL = files.first?.url { @@ -70,7 +69,24 @@ class OpenInAction: Action { // Present UIDocumentInteractionController self.interactionController = UIDocumentInteractionController(url: fileURL) self.interactionController?.delegate = self - self.interactionController?.presentOptionsMenu(from: .zero, in: viewController.view, animated: true) + + if let sender = self.context.sender as? UITabBarController { + var sourceRect = sender.view.frame + sourceRect.origin.y = viewController.view.frame.size.height + sourceRect.size.width = 0.0 + sourceRect.size.height = 0.0 + + self.interactionController?.presentOptionsMenu(from: sourceRect, in: sender.view, animated: true) + } else if let barButtonItem = self.context.sender as? UIBarButtonItem { + self.interactionController?.presentOptionsMenu(from: barButtonItem, animated: true) + } else if let cell = self.context.sender as? UITableViewCell, let clientQueryViewController = viewController as? ClientQueryViewController { + if let indexPath = clientQueryViewController.tableView.indexPath(for: cell) { + let cellRect = clientQueryViewController.tableView.rectForRow(at: indexPath) + self.interactionController?.presentOptionsMenu(from: cellRect, in: clientQueryViewController.tableView, animated: true) + } + } else { + self.interactionController?.presentOptionsMenu(from: viewController.view.frame, in: viewController.view, animated: true) + } } } else { // Handle multiple files with a fallback solution @@ -80,7 +96,18 @@ class OpenInAction: Action { let activityController = UIActivityViewController(activityItems: urls, applicationActivities: nil) if UIDevice.current.isIpad() { - activityController.popoverPresentationController?.sourceView = viewController.view + if let sender = self.context.sender as? UITabBarController { + var sourceRect = sender.view.frame + sourceRect.origin.y = viewController.view.frame.size.height + sourceRect.size.width = 0.0 + sourceRect.size.height = 0.0 + + activityController.popoverPresentationController?.sourceView = sender.view + activityController.popoverPresentationController?.sourceRect = sourceRect + } else { + activityController.popoverPresentationController?.sourceView = viewController.view + activityController.popoverPresentationController?.sourceRect = viewController.view.frame + } } viewController.present(activityController, animated: true, completion: nil) diff --git a/ownCloud/Client/Actions/ClientDirectoryPickerViewController.swift b/ownCloud/Client/Actions/ClientDirectoryPickerViewController.swift index 9b4e7d429..5615d3058 100644 --- a/ownCloud/Client/Actions/ClientDirectoryPickerViewController.swift +++ b/ownCloud/Client/Actions/ClientDirectoryPickerViewController.swift @@ -219,7 +219,7 @@ class ClientDirectoryPickerViewController: ClientQueryViewController { // Actions for Create Folder if let core = self.core, let rootItem = query.rootItem { let actionsLocation = OCExtensionLocation(ofType: .action, identifier: .folderAction) - let actionContext = ActionContext(viewController: self, core: core, items: [rootItem], location: actionsLocation) + let actionContext = ActionContext(viewController: self, core: core, items: [rootItem], location: actionsLocation, sender: sender) let actions = Action.sortedApplicableActions(for: actionContext).filter { (action) -> Bool in if action.actionExtension.identifier == OCExtensionIdentifier("com.owncloud.action.createFolder") { diff --git a/ownCloud/Client/ClientQueryViewController.swift b/ownCloud/Client/ClientQueryViewController.swift index 7bdb2d7d4..b9e7e0679 100644 --- a/ownCloud/Client/ClientQueryViewController.swift +++ b/ownCloud/Client/ClientQueryViewController.swift @@ -233,12 +233,12 @@ class ClientQueryViewController: QueryFileListTableViewController, UIDropInterac } override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { - guard let core = self.core, let item : OCItem = itemAt(indexPath: indexPath) else { + guard let core = self.core, let item : OCItem = itemAt(indexPath: indexPath), let cell = tableView.cellForRow(at: indexPath) else { return nil } let actionsLocation = OCExtensionLocation(ofType: .action, identifier: .tableRow) - let actionContext = ActionContext(viewController: self, core: core, items: [item], location: actionsLocation) + let actionContext = ActionContext(viewController: self, core: core, items: [item], location: actionsLocation, sender: cell) let actions = Action.sortedApplicableActions(for: actionContext) actions.forEach({ $0.progressHandler = makeActionProgressHandler() @@ -453,6 +453,7 @@ class ClientQueryViewController: QueryFileListTableViewController, UIDropInterac // Find associated action if let action = self.actions?.first(where: {type(of:$0).identifier == sender.actionIdentifier}) { // Configure progress handler + action.context.sender = self.tabBarController action.progressHandler = makeActionProgressHandler() action.completionHandler = { [weak self] (_, _) in @@ -523,7 +524,7 @@ class ClientQueryViewController: QueryFileListTableViewController, UIDropInterac // Actions for folderAction if let core = self.core, let rootItem = query.rootItem { let actionsLocation = OCExtensionLocation(ofType: .action, identifier: .folderAction) - let actionContext = ActionContext(viewController: self, core: core, items: [rootItem], location: actionsLocation) + let actionContext = ActionContext(viewController: self, core: core, items: [rootItem], location: actionsLocation, sender: sender) let actions = Action.sortedApplicableActions(for: actionContext) @@ -552,7 +553,7 @@ class ClientQueryViewController: QueryFileListTableViewController, UIDropInterac } let actionsLocation = OCExtensionLocation(ofType: .action, identifier: .moreFolder) - let actionContext = ActionContext(viewController: self, core: core, query: query, items: [rootItem], location: actionsLocation) + let actionContext = ActionContext(viewController: self, core: core, query: query, items: [rootItem], location: actionsLocation, sender: sender) if let moreViewController = Action.cardViewController(for: rootItem, with: actionContext, progressHandler: makeActionProgressHandler()) { self.present(asCard: moreViewController, animated: true) diff --git a/ownCloud/Client/Viewer/DisplayViewController.swift b/ownCloud/Client/Viewer/DisplayViewController.swift index 216aea897..cce799a2d 100644 --- a/ownCloud/Client/Viewer/DisplayViewController.swift +++ b/ownCloud/Client/Viewer/DisplayViewController.swift @@ -379,13 +379,13 @@ class DisplayViewController: UIViewController, OCQueryDelegate { //self.showPreviewButton?.isHidden = false } - @objc func optionsBarButtonPressed() { + @objc func optionsBarButtonPressed(_ sender: UIBarButtonItem) { guard let core = core, let item = item else { return } let actionsLocation = OCExtensionLocation(ofType: .action, identifier: .moreItem) - let actionContext = ActionContext(viewController: self, core: core, items: [item], location: actionsLocation) + let actionContext = ActionContext(viewController: self, core: core, items: [item], location: actionsLocation, sender: sender) if let moreViewController = Action.cardViewController(for: item, with: actionContext, completionHandler: nil) { self.present(asCard: moreViewController, animated: true) diff --git a/ownCloud/FileLists/FileListTableViewController.swift b/ownCloud/FileLists/FileListTableViewController.swift index 298317f78..ebca48488 100644 --- a/ownCloud/FileLists/FileListTableViewController.swift +++ b/ownCloud/FileLists/FileListTableViewController.swift @@ -72,7 +72,7 @@ class FileListTableViewController: UITableViewController, ClientItemCellDelegate } let actionsLocation = OCExtensionLocation(ofType: .action, identifier: .moreItem) - let actionContext = ActionContext(viewController: self, core: core, query: query, items: [item], location: actionsLocation) + let actionContext = ActionContext(viewController: self, core: core, query: query, items: [item], location: actionsLocation, sender: cell) if let moreViewController = Action.cardViewController(for: item, with: actionContext, progressHandler: makeActionProgressHandler()) { self.present(asCard: moreViewController, animated: true)