Marino Faggiana 6 жил өмнө
parent
commit
ee59e5557a
54 өөрчлөгдсөн 2736 нэмэгдсэн , 5 устгасан
  1. 25 0
      Libraries external/Sheeeeeeeeet/ActionSheet/ActionSheet+Presenter.swift
  2. 368 0
      Libraries external/Sheeeeeeeeet/ActionSheet/ActionSheet.swift
  3. 83 0
      Libraries external/Sheeeeeeeeet/ActionSheet/ActionSheetItemHandler.swift
  4. 33 0
      Libraries external/Sheeeeeeeeet/ActionSheet/ActionSheetMargin.swift
  5. 144 0
      Libraries external/Sheeeeeeeeet/Appearance/ActionSheetAppearance.swift
  6. 54 0
      Libraries external/Sheeeeeeeeet/Appearance/ActionSheetItemAppearance.swift
  7. 28 0
      Libraries external/Sheeeeeeeeet/Appearance/ActionSheetPopoverApperance.swift
  8. 11 0
      Libraries external/Sheeeeeeeeet/Appearance/Buttons/ActionSheetButtonItemAppearance.swift
  9. 11 0
      Libraries external/Sheeeeeeeeet/Appearance/Buttons/ActionSheetCancelButtonAppearance.swift
  10. 11 0
      Libraries external/Sheeeeeeeeet/Appearance/Buttons/ActionSheetDangerButtonAppearance.swift
  11. 11 0
      Libraries external/Sheeeeeeeeet/Appearance/Buttons/ActionSheetOkButtonAppearance.swift
  12. 11 0
      Libraries external/Sheeeeeeeeet/Appearance/Items/ActionSheetCollectionItemAppearance.swift
  13. 11 0
      Libraries external/Sheeeeeeeeet/Appearance/Items/ActionSheetCustomItemAppearance.swift
  14. 30 0
      Libraries external/Sheeeeeeeeet/Appearance/Items/ActionSheetLinkItemAppearance.swift
  15. 11 0
      Libraries external/Sheeeeeeeeet/Appearance/Items/ActionSheetMultiSelectItemAppearance.swift
  16. 32 0
      Libraries external/Sheeeeeeeeet/Appearance/Items/ActionSheetMultiSelectToggleItemAppearance.swift
  17. 51 0
      Libraries external/Sheeeeeeeeet/Appearance/Items/ActionSheetSelectItemAppearance.swift
  18. 11 0
      Libraries external/Sheeeeeeeeet/Appearance/Items/ActionSheetSingleSelectItemAppearance.swift
  19. 25 0
      Libraries external/Sheeeeeeeeet/Appearance/Titles/ActionSheetSectionMarginAppearance.swift
  20. 11 0
      Libraries external/Sheeeeeeeeet/Appearance/Titles/ActionSheetSectionTitleAppearance.swift
  21. 11 0
      Libraries external/Sheeeeeeeeet/Appearance/Titles/ActionSheetTitleAppearance.swift
  22. 16 0
      Libraries external/Sheeeeeeeeet/Extensions/NSObject+ClassName.swift
  23. 18 0
      Libraries external/Sheeeeeeeeet/Extensions/UIView+Empty.swift
  24. 17 0
      Libraries external/Sheeeeeeeeet/Extensions/UIViewController+RootViewController.swift
  25. 111 0
      Libraries external/Sheeeeeeeeet/Items/ActionSheetItem.swift
  26. 44 0
      Libraries external/Sheeeeeeeeet/Items/Buttons/ActionSheetButton.swift
  27. 34 0
      Libraries external/Sheeeeeeeeet/Items/Buttons/ActionSheetCancelButton.swift
  28. 35 0
      Libraries external/Sheeeeeeeeet/Items/Buttons/ActionSheetDangerButton.swift
  29. 35 0
      Libraries external/Sheeeeeeeeet/Items/Buttons/ActionSheetOkButton.swift
  30. 130 0
      Libraries external/Sheeeeeeeeet/Items/Items/ActionSheetCollectionItem.swift
  31. 64 0
      Libraries external/Sheeeeeeeeet/Items/Items/ActionSheetCustomItem.swift
  32. 40 0
      Libraries external/Sheeeeeeeeet/Items/Items/ActionSheetLinkItem.swift
  33. 62 0
      Libraries external/Sheeeeeeeeet/Items/Items/ActionSheetMultiSelectItem.swift
  34. 86 0
      Libraries external/Sheeeeeeeeet/Items/Items/ActionSheetMultiSelectToggleItem.swift
  35. 82 0
      Libraries external/Sheeeeeeeeet/Items/Items/ActionSheetSelectItem.swift
  36. 57 0
      Libraries external/Sheeeeeeeeet/Items/Items/ActionSheetSingleSelectItem.swift
  37. 44 0
      Libraries external/Sheeeeeeeeet/Items/Titles/ActionSheetSectionMargin.swift
  38. 49 0
      Libraries external/Sheeeeeeeeet/Items/Titles/ActionSheetSectionTitle.swift
  39. 45 0
      Libraries external/Sheeeeeeeeet/Items/Titles/ActionSheetTitle.swift
  40. 151 0
      Libraries external/Sheeeeeeeeet/Presenters/ActionSheetDefaultPresenter.swift
  41. 112 0
      Libraries external/Sheeeeeeeeet/Presenters/ActionSheetPopoverPresenter.swift
  42. 43 0
      Libraries external/Sheeeeeeeeet/Presenters/ActionSheetPresenter.swift
  43. 19 0
      Libraries external/Sheeeeeeeeet/Sheeeeeeeeet.h
  44. 34 0
      Libraries external/Sheeeeeeeeet/Views/ActionSheetCollectionItemCell.swift
  45. 46 0
      Libraries external/Sheeeeeeeeet/Views/ActionSheetCollectionItemCell.xib
  46. 27 0
      Libraries external/Sheeeeeeeeet/Views/ActionSheetCollectionItemContentCell.swift
  47. 22 0
      Libraries external/Sheeeeeeeeet/Views/ActionSheetCustomItemCell.swift
  48. 19 0
      Libraries external/Sheeeeeeeeet/Views/ActionSheetItemCell.swift
  49. 294 0
      Nextcloud.xcodeproj/project.pbxproj
  50. 1 1
      iOSClient/Brand/File_Provider_Extension.plist
  51. 1 1
      iOSClient/Brand/Notification_Service_Extension.plist
  52. 1 1
      iOSClient/Brand/Share.plist
  53. 1 1
      iOSClient/Brand/iOSClient.plist
  54. 13 1
      iOSClient/Trash/NCTrash.swift

+ 25 - 0
Libraries external/Sheeeeeeeeet/ActionSheet/ActionSheet+Presenter.swift

@@ -0,0 +1,25 @@
+//
+//  ActionSheet+Presenter.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2018-04-27.
+//  Copyright © 2018 Daniel Saidi. All rights reserved.
+//
+
+public extension ActionSheet {
+    
+    static var defaultPresenter: ActionSheetPresenter {
+        return defaultPresenter(for: UIDevice.current.userInterfaceIdiom)
+    }
+}
+
+
+// MARK: - Internal Extensions
+
+extension ActionSheet {
+    
+    static func defaultPresenter(for idiom: UIUserInterfaceIdiom) -> ActionSheetPresenter {
+        let isIpad = idiom == .pad
+        return isIpad ? ActionSheetPopoverPresenter() : ActionSheetDefaultPresenter()
+    }
+}

+ 368 - 0
Libraries external/Sheeeeeeeeet/ActionSheet/ActionSheet.swift

@@ -0,0 +1,368 @@
+//
+//  ActionSheet.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2017-11-26.
+//  Copyright © 2017 Daniel Saidi. All rights reserved.
+//
+
+/*
+ 
+ This is the main class in the Sheeeeeeeeet library. You can
+ use it to create action sheets and present them in any view
+ controller, from any source view or bar button item.
+ 
+ To create an action sheet, just call the initializer with a
+ list of items and buttons and a block that should be called
+ whenever an item is selected.
+ 
+ 
+ ## Custom presentation
+ 
+ You can also inject a custom sheet presenter if you want to
+ customize how your sheet is presented and dismissed. If you
+ do not use a custom presenter, `ActionSheetDefaultPresenter`
+ is used. It honors the default iOS behavior by using action
+ sheets on iPhones and popovers on iPad.
+ 
+ 
+ ## Subclassing
+ 
+ `ActionSheet` can be subclassed, which may be nice whenever
+ you use Sheeeeeeeeet in your own app and want to use an app
+ specific domain model. For instance, if you want to present
+ a list of `Food` items, you could create a `FoodActionSheet`
+ subclass, that is responsible to populate itself with items.
+ When you subclass `ActionSheet` you can either override the
+ initializers. However, you could also just override `setup`
+ and configure the action sheet in your override.
+ 
+ 
+ ## Appearance
+ 
+ Sheeeeeeeeet's action sheet appearance if easily customized.
+ To change the global appearance for every action sheet that
+ is used in your app, use `UIActionSheetAppearance.standard`.
+ To change the appearance of a single action sheet, use it's
+ `appearance` property. To change the appearance of a single
+ item, use it's `appearance` property.
+ 
+ 
+ ## Triggered actions
+ 
+ `ActionSheet` has two actions that are triggered by tapping
+ an item. `itemTapAction` is used by the sheet itself when a
+ tap occurs on an item. You can override this if you want to,
+ but you don't have to. `itemSelectAction`, however, must be
+ set to detect when an item is selected after a tap. This is
+ the main item action to observe, and the action you provide
+ in the initializer.
+ 
+ */
+
+import UIKit
+
+open class ActionSheet: UIViewController {
+    
+    
+    // MARK: - Initialization
+    
+    public init(
+        items: [ActionSheetItem],
+        presenter: ActionSheetPresenter = ActionSheet.defaultPresenter,
+        action: @escaping SelectAction) {
+        self.presenter = presenter
+        itemSelectAction = action
+        super.init(nibName: nil, bundle: nil)
+        setupItemsAndButtons(with: items)
+        setup()
+    }
+    
+    public required init?(coder aDecoder: NSCoder) {
+        presenter = ActionSheet.defaultPresenter
+        itemSelectAction = { _, _ in print("itemSelectAction is not set") }
+        super.init(coder: aDecoder)
+        setup()
+    }
+    
+    deinit { print("\(type(of: self)) deinit") }
+    
+    
+    // MARK: - Setup
+    
+    open func setup() {
+        view.backgroundColor = .clear
+    }
+    
+    
+    // MARK: - View Controller Lifecycle
+    
+    open override func viewDidLayoutSubviews() {
+        super.viewDidLayoutSubviews()
+        prepareForPresentation()
+    }
+    
+    
+    // MARK: - Typealiases
+    
+    public typealias SelectAction = (ActionSheet, ActionSheetItem) -> ()
+    public typealias TapAction = (ActionSheetItem) -> ()
+    
+    
+    // MARK: - Dependencies
+    
+    open var appearance = ActionSheetAppearance(copy: .standard)
+    
+    open var presenter: ActionSheetPresenter
+    
+    
+    // MARK: - Actions
+    
+    open var itemSelectAction: SelectAction
+    
+    open lazy var itemTapAction: TapAction = { [weak self] item in
+        self?.handleTap(on: item)
+    }
+    
+    
+    // MARK: - Item Properties
+    
+    open var buttons = [ActionSheetButton]()
+    
+    open var items = [ActionSheetItem]()
+    
+    
+    // MARK: - Properties
+    
+    open var availableItemHeight: CGFloat {
+        return UIScreen.main.bounds.height
+            - 2 * margin(at: .top)
+            - margin(at: .bottom)
+            - headerSectionHeight
+            - buttonsSectionHeight
+    }
+    
+    open var bottomPresentationFrame: CGRect {
+        guard let view = view.superview else { return .zero }
+        var frame = view.frame
+        let leftMargin = margin(at: .left)
+        let rightMargin = margin(at: .right)
+        let maxMargin = max(leftMargin, rightMargin)
+        frame = frame.insetBy(dx: maxMargin, dy: 0)
+        frame.size.height = contentHeight
+        frame.origin.y = view.frame.height - contentHeight
+        frame.origin.y -= margin(at: .bottom)
+        return frame
+    }
+    
+    open var buttonsSectionHeight: CGFloat {
+        return buttonsViewHeight
+    }
+    
+    open var buttonsViewHeight: CGFloat {
+        return buttons.reduce(0) { $0 + $1.appearance.height }
+    }
+    
+    open var contentHeight: CGFloat {
+        return headerSectionHeight + itemsSectionHeight + buttonsSectionHeight
+    }
+    
+    open var contentWidth: CGFloat {
+        return super.preferredContentSize.width
+    }
+    
+    open var headerSectionHeight: CGFloat {
+        guard headerViewHeight > 0 else { return 0 }
+        return headerViewHeight + appearance.contentInset
+    }
+    
+    open var headerViewHeight: CGFloat {
+        return headerView?.frame.height ?? 0
+    }
+    
+    open var itemsSectionHeight: CGFloat {
+        guard itemsViewHeight > 0 else { return 0 }
+        guard buttonsSectionHeight > 0 else { return itemsViewHeight }
+        return itemsViewHeight + appearance.contentInset
+    }
+    
+    open var itemsViewHeight: CGFloat {
+        let required = requiredItemHeight
+        let available = availableItemHeight
+        return min(required, available)
+    }
+    
+    open var itemsViewRequiresScrolling: Bool {
+        let required = requiredItemHeight
+        let available = availableItemHeight
+        return available < required
+    }
+    
+    open override var preferredContentSize: CGSize {
+        get { return CGSize(width: contentWidth, height: contentHeight) }
+        set { super.preferredContentSize = newValue }
+    }
+    
+    open var preferredPopoverSize: CGSize {
+        let width = appearance.popover.width
+        return CGSize(width: width, height: contentHeight)
+    }
+    
+    open var requiredItemHeight: CGFloat {
+        return items.reduce(0) { $0 + $1.appearance.height }
+    }
+
+
+    // MARK: - View Properties
+    
+    open lazy var buttonsView: UITableView = {
+        let tableView = createTableView(handler: buttonHandler)
+        view.addSubview(tableView)
+        return tableView
+    }()
+
+    open var headerView: UIView? {
+        didSet {
+            oldValue?.removeFromSuperview()
+            guard let header = headerView else { return }
+            view.addSubview(header)
+        }
+    }
+    
+    open lazy var itemsView: UITableView = {
+        let tableView = createTableView(handler: itemHandler)
+        view.addSubview(tableView)
+        return tableView
+    }()
+    
+    
+    // MARK: - Data Properties
+    
+    public lazy var buttonHandler = ActionSheetItemHandler(actionSheet: self, handles: .buttons)
+    
+    public lazy var itemHandler = ActionSheetItemHandler(actionSheet: self, handles: .items)
+
+    
+    // MARK: - Presentation Functions
+    
+    open func applyAppearance() {
+        itemsView.separatorColor = appearance.itemsSeparatorColor
+        buttonsView.separatorColor = appearance.buttonsSeparatorColor
+    }
+    
+    open func dismiss(completion: @escaping () -> ()) {
+        presenter.dismiss { completion() }
+    }
+    
+    open func present(in vc: UIViewController, from view: UIView?) {
+        prepareForPresentation()
+        presenter.present(sheet: self, in: vc.rootViewController, from: view)
+    }
+    
+    open func present(in vc: UIViewController, from barButtonItem: UIBarButtonItem) {
+        prepareForPresentation()
+        presenter.present(sheet: self, in: vc.rootViewController, from: barButtonItem)
+    }
+    
+    open func prepareForPresentation() {
+        applyAppearance()
+        items.forEach { $0.applyAppearance(appearance) }
+        buttons.forEach { $0.applyAppearance(appearance) }
+        applyRoundCorners()
+        positionViews()
+    }
+    
+    
+    // MARK: - Public Functions
+    
+    open func margin(at margin: ActionSheetMargin) -> CGFloat {
+        let minimum = appearance.contentInset
+        return margin.value(in: view.superview, minimum: minimum)
+    }
+    
+    public func item(at indexPath: IndexPath) -> ActionSheetItem {
+        return items[indexPath.row]
+    }
+    
+    open func reloadData() {
+        itemsView.reloadData()
+        buttonsView.reloadData()
+    }
+    
+    open func setupItemsAndButtons(with items: [ActionSheetItem]) {
+        self.items = items.filter { !($0 is ActionSheetButton) }
+        buttons = items.compactMap { $0 as? ActionSheetButton }
+        reloadData()
+    }
+}
+
+
+// MARK: - Private Functions
+
+private extension ActionSheet {
+    
+    func applyRoundCorners() {
+        applyRoundCorners(to: headerView)
+        applyRoundCorners(to: itemsView)
+        applyRoundCorners(to: buttonsView)
+    }
+    
+    func applyRoundCorners(to view: UIView?) {
+        view?.clipsToBounds = true
+        view?.layer.cornerRadius = appearance.cornerRadius
+    }
+    
+    func createTableView(handler: ActionSheetItemHandler) -> UITableView {
+        let tableView = UITableView(frame: view.frame, style: .plain)
+        tableView.isScrollEnabled = false
+        tableView.tableFooterView = UIView.empty
+        tableView.cellLayoutMarginsFollowReadableWidth = false
+        tableView.dataSource = handler
+        tableView.delegate = handler
+        return tableView
+    }
+    
+    func handleTap(on item: ActionSheetItem) {
+        reloadData()
+        if item.tapBehavior == .dismiss {
+            dismiss { self.itemSelectAction(self, item) }
+        } else {
+            itemSelectAction(self, item)
+        }
+    }
+    
+    func positionViews() {
+        let width = view.frame.width
+        positionHeaderView(width: width)
+        positionItemsView(width: width)
+        positionButtonsView(width: width)
+        positionSheet()
+    }
+    
+    func positionSheet() {
+        guard let superview = view.superview else { return }
+        guard let frame = presenter.presentationFrame(for: self, in: superview) else { return }
+        view.frame = frame
+    }
+    
+    func positionButtonsView(width: CGFloat) {
+        buttonsView.frame.origin.x = 0
+        buttonsView.frame.origin.y = headerSectionHeight + itemsSectionHeight
+        buttonsView.frame.size.width = width
+        buttonsView.frame.size.height = buttonsViewHeight
+    }
+    
+    func positionHeaderView(width: CGFloat) {
+        guard let view = headerView else { return }
+        view.frame.origin = .zero
+        view.frame.size.width = width
+    }
+    
+    func positionItemsView(width: CGFloat) {
+        itemsView.frame.origin.x = 0
+        itemsView.frame.origin.y = headerSectionHeight
+        itemsView.frame.size.width = width
+        itemsView.frame.size.height = itemsViewHeight
+        itemsView.isScrollEnabled = itemsViewRequiresScrolling
+    }
+}

+ 83 - 0
Libraries external/Sheeeeeeeeet/ActionSheet/ActionSheetItemHandler.swift

@@ -0,0 +1,83 @@
+//
+//  ActionSheetItemHandler.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2017-11-24.
+//  Copyright © 2017 Daniel Saidi. All rights reserved.
+//
+
+import UIKit
+
+open class ActionSheetItemHandler: NSObject {
+    
+    
+    // MARK: - Initialization
+    
+    init(actionSheet: ActionSheet, handles itemType: ItemType) {
+        self.actionSheet = actionSheet
+        self.itemType = itemType
+    }
+    
+    
+    // MARK: - Enum
+    
+    public enum ItemType {
+        case items, buttons
+    }
+    
+    
+    // MARK: - Properties
+    
+    private weak var actionSheet: ActionSheet?
+    
+    private var itemType: ItemType
+    
+    private var items: [ActionSheetItem] {
+        switch itemType {
+        case .buttons: return actionSheet?.buttons ?? []
+        case .items: return actionSheet?.items ?? []
+        }
+    }
+}
+
+
+// MARK: - UITableViewDataSource
+
+extension ActionSheetItemHandler: UITableViewDataSource {
+    
+    public func item(at indexPath: IndexPath) -> ActionSheetItem {
+        return items[indexPath.row]
+    }
+    
+    public func numberOfSections(in tableView: UITableView) -> Int {
+        return 1
+    }
+    
+    public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+        return items.count
+    }
+    
+    public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+        return item(at: indexPath).cell(for: tableView)
+    }
+    
+    public func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
+        return CGFloat(item(at: indexPath).appearance.height)
+    }
+}
+
+
+// MARK: - UITableViewDelegate
+
+extension ActionSheetItemHandler: UITableViewDelegate {
+    
+    public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+        guard items.count > indexPath.row else { return }
+        let item = self.item(at: indexPath)
+        let cell = tableView.cellForRow(at: indexPath)
+        tableView.deselectRow(at: indexPath, animated: true)
+        guard let sheet = actionSheet else { return }
+        item.handleTap(in: sheet, cell: cell)
+        sheet.itemTapAction(item)
+    }
+}

+ 33 - 0
Libraries external/Sheeeeeeeeet/ActionSheet/ActionSheetMargin.swift

@@ -0,0 +1,33 @@
+//
+//  ActionSheetMargin.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2018-02-22.
+//  Copyright © 2018 Daniel Saidi. All rights reserved.
+//
+
+import UIKit
+
+public enum ActionSheetMargin {
+    case top, left, right, bottom
+    
+    func value(in view: UIView?) -> CGFloat? {
+        guard let view = view else { return nil }
+        if #available(iOS 11.0, *) {
+            let insets = view.safeAreaInsets
+            switch self {
+            case .top: return insets.top
+            case .left: return insets.left
+            case .right: return insets.right
+            case .bottom: return insets.bottom
+            }
+        } else {
+            return nil
+        }
+    }
+    
+    func value(in view: UIView?, minimum: CGFloat) -> CGFloat {
+        guard let value = self.value(in: view) else { return minimum }
+        return max(value, minimum)
+    }
+}

+ 144 - 0
Libraries external/Sheeeeeeeeet/Appearance/ActionSheetAppearance.swift

@@ -0,0 +1,144 @@
+//
+//  ActionSheetAppearance.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2017-11-18.
+//  Copyright © 2017 Daniel Saidi. All rights reserved.
+//
+
+/*
+ 
+ This class is used to specify the appearance for all action
+ sheets and action sheet items provided by Sheeeeeeeeet. Use
+ `ActionSheetAppearance.standard` to style all action sheets
+ in an entire app. You can then apply individual appearances
+ to individual action sheets and item types.
+ 
+ The `item` appearance property is used as the base template
+ for all other item appearances.
+ 
+ */
+
+import UIKit
+
+open class ActionSheetAppearance {
+    
+    
+    // MARK: - Initialization
+    
+    public init() {}
+    
+    public init(copy: ActionSheetAppearance) {
+        cornerRadius = copy.cornerRadius
+        contentInset = copy.contentInset
+        
+        separatorColor = copy.separatorColor
+        itemsSeparatorColor = copy.itemsSeparatorColor ?? separatorColor
+        buttonsSeparatorColor = copy.buttonsSeparatorColor ?? separatorColor
+        
+        item = ActionSheetItemAppearance(copy: copy.item)
+        popover = ActionSheetPopoverApperance(copy: copy.popover)
+        
+        cancelButton = ActionSheetCancelButtonAppearance(copy: copy.cancelButton)
+        dangerButton = ActionSheetDangerButtonAppearance(copy: copy.dangerButton)
+        okButton = ActionSheetOkButtonAppearance(copy: copy.okButton)
+        
+        collectionItem = ActionSheetCollectionItemAppearance(copy: copy.collectionItem)
+        customItem = ActionSheetCustomItemAppearance(copy: copy.customItem)
+        linkItem = ActionSheetLinkItemAppearance(copy: copy.linkItem)
+        multiSelectItem = ActionSheetMultiSelectItemAppearance(copy: copy.multiSelectItem)
+        multiSelectToggleItem = ActionSheetMultiSelectToggleItemAppearance(copy: copy.multiSelectToggleItem)
+        selectItem = ActionSheetSelectItemAppearance(copy: copy.selectItem)
+        singleSelectItem = ActionSheetSingleSelectItemAppearance(copy: copy.singleSelectItem)
+        
+        sectionMargin = ActionSheetSectionMarginAppearance(copy: copy.sectionMargin)
+        sectionTitle = ActionSheetSectionTitleAppearance(copy: copy.sectionTitle)
+        title = ActionSheetTitleAppearance(copy: copy.title)
+    }
+    
+    
+    // MARK: - Properties
+    
+    public var cornerRadius: CGFloat = 10
+    public var contentInset: CGFloat = 15
+    
+    public var separatorColor: UIColor?
+    public var itemsSeparatorColor: UIColor?
+    public var buttonsSeparatorColor: UIColor?
+    
+    
+    // MARK: - Appearance Properties
+    
+    public static var standard = ActionSheetAppearance()
+    
+    public lazy var item: ActionSheetItemAppearance = {
+        return ActionSheetItemAppearance()
+    }()
+    
+    public lazy var popover: ActionSheetPopoverApperance = {
+        return ActionSheetPopoverApperance(width: 300)
+    }()
+    
+    
+    // MARK: - Buttons
+    
+    public lazy var cancelButton: ActionSheetCancelButtonAppearance = {
+        return ActionSheetCancelButtonAppearance(copy: item)
+    }()
+    
+    public lazy var dangerButton: ActionSheetDangerButtonAppearance = {
+        let appearance = ActionSheetDangerButtonAppearance(copy: item)
+        appearance.textColor = .red
+        return appearance
+    }()
+    
+    public lazy var okButton: ActionSheetOkButtonAppearance = {
+        return ActionSheetOkButtonAppearance(copy: item)
+    }()
+    
+    
+    // MARK: - Items
+    
+    public lazy var collectionItem: ActionSheetCollectionItemAppearance = {
+        return ActionSheetCollectionItemAppearance(copy: item)
+    }()
+    
+    public lazy var customItem: ActionSheetCustomItemAppearance = {
+        return ActionSheetCustomItemAppearance(copy: item)
+    }()
+    
+    public lazy var linkItem: ActionSheetLinkItemAppearance = {
+        return ActionSheetLinkItemAppearance(copy: item)
+    }()
+    
+    public lazy var multiSelectItem: ActionSheetMultiSelectItemAppearance = {
+        return ActionSheetMultiSelectItemAppearance(copy: selectItem)
+    }()
+    
+    public lazy var multiSelectToggleItem: ActionSheetMultiSelectToggleItemAppearance = {
+        return ActionSheetMultiSelectToggleItemAppearance(copy: item)
+    }()
+    
+    public lazy var selectItem: ActionSheetSelectItemAppearance = {
+        return ActionSheetSelectItemAppearance(copy: item)
+    }()
+    
+    public lazy var singleSelectItem: ActionSheetSingleSelectItemAppearance = {
+        return ActionSheetSingleSelectItemAppearance(copy: selectItem)
+    }()
+    
+    
+    // MARK: - Titles
+    
+    public lazy var sectionMargin: ActionSheetSectionMarginAppearance = {
+        return ActionSheetSectionMarginAppearance(copy: item)
+    }()
+    
+    public lazy var sectionTitle: ActionSheetSectionTitleAppearance = {
+        return ActionSheetSectionTitleAppearance(copy: item)
+    }()
+    
+    public lazy var title: ActionSheetTitleAppearance = {
+        return ActionSheetTitleAppearance(copy: item)
+    }()
+}

+ 54 - 0
Libraries external/Sheeeeeeeeet/Appearance/ActionSheetItemAppearance.swift

@@ -0,0 +1,54 @@
+//
+//  ActionSheetItemAppearance.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2017-11-24.
+//  Copyright © 2017 Daniel Saidi. All rights reserved.
+//
+
+import UIKit
+
+open class ActionSheetItemAppearance {
+    
+    
+    // MARK: - Initialization
+    
+    public init() {}
+    
+    public init(copy: ActionSheetItemAppearance) {
+        backgroundColor = copy.backgroundColor
+        font = copy.font
+        height = copy.height
+        separatorInsets = copy.separatorInsets
+        textColor = copy.textColor
+        tintColor = copy.tintColor
+        subtitleFont = copy.subtitleFont
+        subtitleTextColor = copy.subtitleTextColor
+    }
+    
+    
+    // MARK: - Properties
+    
+    public var backgroundColor: UIColor?
+    public var font: UIFont?
+    public var height: CGFloat = 50
+    public var separatorInsets: UIEdgeInsets = .zero
+    public var textColor: UIColor?
+    public var tintColor: UIColor?
+    public var subtitleFont: UIFont?
+    public var subtitleTextColor: UIColor?
+}
+
+
+// MARK: - Public Extensions
+
+public extension ActionSheetItemAppearance {
+    
+    public static var noSeparator: UIEdgeInsets {
+        return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: UIScreen.main.bounds.width)
+    }
+    
+    public func hideSeparator() {
+        separatorInsets = ActionSheetItemAppearance.noSeparator
+    }
+}

+ 28 - 0
Libraries external/Sheeeeeeeeet/Appearance/ActionSheetPopoverApperance.swift

@@ -0,0 +1,28 @@
+//
+//  ActionSheetPopoverApperance.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2017-11-24.
+//  Copyright © 2017 Daniel Saidi. All rights reserved.
+//
+
+import UIKit
+
+open class ActionSheetPopoverApperance {
+    
+    
+    // MARK: - Initialization
+    
+    public init(width: CGFloat) {
+        self.width = width
+    }
+    
+    public init(copy: ActionSheetPopoverApperance) {
+        self.width = copy.width
+    }
+    
+    
+    // MARK: - Properties
+    
+    public var width: CGFloat
+}

+ 11 - 0
Libraries external/Sheeeeeeeeet/Appearance/Buttons/ActionSheetButtonItemAppearance.swift

@@ -0,0 +1,11 @@
+//
+//  ActionSheetButtonItemAppearance.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2017-11-24.
+//  Copyright © 2017 Daniel Saidi. All rights reserved.
+//
+
+import UIKit
+
+open class ActionSheetButtonAppearance: ActionSheetItemAppearance {}

+ 11 - 0
Libraries external/Sheeeeeeeeet/Appearance/Buttons/ActionSheetCancelButtonAppearance.swift

@@ -0,0 +1,11 @@
+//
+//  ActionSheetCancelButtonAppearance.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2017-11-24.
+//  Copyright © 2017 Daniel Saidi. All rights reserved.
+//
+
+import UIKit
+
+open class ActionSheetCancelButtonAppearance: ActionSheetButtonAppearance {}

+ 11 - 0
Libraries external/Sheeeeeeeeet/Appearance/Buttons/ActionSheetDangerButtonAppearance.swift

@@ -0,0 +1,11 @@
+//
+//  ActionSheetDangerButtonAppearance.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2017-11-27.
+//  Copyright © 2017 Daniel Saidi. All rights reserved.
+//
+
+import UIKit
+
+open class ActionSheetDangerButtonAppearance: ActionSheetButtonAppearance {}

+ 11 - 0
Libraries external/Sheeeeeeeeet/Appearance/Buttons/ActionSheetOkButtonAppearance.swift

@@ -0,0 +1,11 @@
+//
+//  ActionSheetOkButtonAppearance.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2017-11-24.
+//  Copyright © 2017 Daniel Saidi. All rights reserved.
+//
+
+import UIKit
+
+open class ActionSheetOkButtonAppearance: ActionSheetButtonAppearance {}

+ 11 - 0
Libraries external/Sheeeeeeeeet/Appearance/Items/ActionSheetCollectionItemAppearance.swift

@@ -0,0 +1,11 @@
+//
+//  ActionSheetCollectionItemAppearance.swift
+//  SheeeeeeeeetExample
+//
+//  Created by Jonas Ullström (ullstrm) on 2018-02-23.
+//  Copyright © 2018 Jonas Ullström. All rights reserved.
+//
+
+import Foundation
+
+open class ActionSheetCollectionItemAppearance: ActionSheetItemAppearance {}

+ 11 - 0
Libraries external/Sheeeeeeeeet/Appearance/Items/ActionSheetCustomItemAppearance.swift

@@ -0,0 +1,11 @@
+//
+//  ActionSheetCustomItemAppearance.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2018-10-08.
+//  Copyright © 2018 Daniel Saidi. All rights reserved.
+//
+
+import Foundation
+
+open class ActionSheetCustomItemAppearance: ActionSheetItemAppearance {}

+ 30 - 0
Libraries external/Sheeeeeeeeet/Appearance/Items/ActionSheetLinkItemAppearance.swift

@@ -0,0 +1,30 @@
+//
+//  ActionSheetLinkItemAppearance.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2017-11-24.
+//  Copyright © 2017 Daniel Saidi. All rights reserved.
+//
+
+import UIKit
+
+open class ActionSheetLinkItemAppearance: ActionSheetItemAppearance {
+    
+    
+    // MARK: - Initialization
+    
+    public override init() {
+        super.init()
+    }
+    
+    public override init(copy: ActionSheetItemAppearance) {
+        super.init(copy: copy)
+        guard let copy = copy as? ActionSheetLinkItemAppearance else { return }
+        linkIcon = copy.linkIcon
+    }
+    
+    
+    // MARK: - Properties
+    
+    public var linkIcon: UIImage?
+}

+ 11 - 0
Libraries external/Sheeeeeeeeet/Appearance/Items/ActionSheetMultiSelectItemAppearance.swift

@@ -0,0 +1,11 @@
+//
+//  ActionSheetMultiSelectItemAppearance.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2018-03-31.
+//  Copyright © 2018 Daniel Saidi. All rights reserved.
+//
+
+import Foundation
+
+open class ActionSheetMultiSelectItemAppearance: ActionSheetSelectItemAppearance {}

+ 32 - 0
Libraries external/Sheeeeeeeeet/Appearance/Items/ActionSheetMultiSelectToggleItemAppearance.swift

@@ -0,0 +1,32 @@
+//
+//  ActionSheetMultiSelectToggleItemAppearance.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2018-03-31.
+//  Copyright © 2018 Daniel Saidi. All rights reserved.
+//
+
+import UIKit
+
+open class ActionSheetMultiSelectToggleItemAppearance: ActionSheetItemAppearance {
+    
+    
+    // MARK: - Initialization
+    
+    public override init() {
+        super.init()
+    }
+    
+    public override init(copy: ActionSheetItemAppearance) {
+        super.init(copy: copy)
+        guard let copy = copy as? ActionSheetMultiSelectToggleItemAppearance else { return }
+        deselectAllTextColor = copy.deselectAllTextColor
+        selectAllTextColor = copy.selectAllTextColor
+    }
+    
+    
+    // MARK: - Properties
+    
+    public var deselectAllTextColor: UIColor?
+    public var selectAllTextColor: UIColor?
+}

+ 51 - 0
Libraries external/Sheeeeeeeeet/Appearance/Items/ActionSheetSelectItemAppearance.swift

@@ -0,0 +1,51 @@
+//
+//  ActionSheetSelectItemAppearance.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2017-11-24.
+//  Copyright © 2017 Daniel Saidi. All rights reserved.
+//
+
+/*
+ 
+ This appearance inherits the base appearance and applies to
+ select items. The additional properties are applied when an
+ item is selected:
+ 
+ * `selectedIcon` is displayed rightmost, e.g. a checkmark
+ * `selectedTextColor` is applied to the text (duh)
+ * `selectedTintColor` is applied to both icons if they are rendered as template images
+ * `selectedIconTintColor` can override `selectedTintColor` for the selected icon
+ 
+ */
+
+import UIKit
+
+open class ActionSheetSelectItemAppearance: ActionSheetItemAppearance {
+    
+    
+    // MARK: - Initialization
+    
+    public override init() {
+        super.init()
+    }
+    
+    public override init(copy: ActionSheetItemAppearance) {
+        super.init(copy: copy)
+        selectedTextColor = copy.textColor
+        selectedTintColor = copy.tintColor
+        guard let copy = copy as? ActionSheetSelectItemAppearance else { return }
+        selectedIcon = copy.selectedIcon
+        selectedTextColor = copy.selectedTextColor ?? selectedTextColor
+        selectedTintColor = copy.selectedTintColor ?? selectedTintColor
+        selectedIconTintColor = copy.selectedIconTintColor ?? selectedTintColor
+    }
+    
+    
+    // MARK: - Properties
+    
+    public var selectedIcon: UIImage?
+    public var selectedIconTintColor: UIColor?
+    public var selectedTextColor: UIColor?
+    public var selectedTintColor: UIColor?
+}

+ 11 - 0
Libraries external/Sheeeeeeeeet/Appearance/Items/ActionSheetSingleSelectItemAppearance.swift

@@ -0,0 +1,11 @@
+//
+//  ActionSheetSingleSelectItemAppearance.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2018-03-19.
+//  Copyright © 2018 Daniel Saidi. All rights reserved.
+//
+
+import Foundation
+
+open class ActionSheetSingleSelectItemAppearance: ActionSheetSelectItemAppearance {}

+ 25 - 0
Libraries external/Sheeeeeeeeet/Appearance/Titles/ActionSheetSectionMarginAppearance.swift

@@ -0,0 +1,25 @@
+//
+//  ActionSheetSectionMarginAppearance.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2017-11-27.
+//  Copyright © 2017 Daniel Saidi. All rights reserved.
+//
+
+import Foundation
+
+open class ActionSheetSectionMarginAppearance: ActionSheetItemAppearance {
+    
+    
+    // MARK: - Initialization
+    
+    public override init() {
+        super.init()
+        hideSeparator()
+    }
+    
+    public override init(copy: ActionSheetItemAppearance) {
+        super.init(copy: copy)
+        hideSeparator()
+    }
+}

+ 11 - 0
Libraries external/Sheeeeeeeeet/Appearance/Titles/ActionSheetSectionTitleAppearance.swift

@@ -0,0 +1,11 @@
+//
+//  ActionSheetSectionTitleAppearance.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2017-11-19.
+//  Copyright © 2017 Daniel Saidi. All rights reserved.
+//
+
+import Foundation
+
+open class ActionSheetSectionTitleAppearance: ActionSheetItemAppearance {}

+ 11 - 0
Libraries external/Sheeeeeeeeet/Appearance/Titles/ActionSheetTitleAppearance.swift

@@ -0,0 +1,11 @@
+//
+//  ActionSheetTitleAppearance.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2017-11-19.
+//  Copyright © 2017 Daniel Saidi. All rights reserved.
+//
+
+import Foundation
+
+open class ActionSheetTitleAppearance: ActionSheetItemAppearance { }

+ 16 - 0
Libraries external/Sheeeeeeeeet/Extensions/NSObject+ClassName.swift

@@ -0,0 +1,16 @@
+//
+//  NSObject+ClassName.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2017-11-24.
+//  Copyright © 2017 Daniel Saidi. All rights reserved.
+//
+
+import UIKit
+
+extension NSObject {
+    
+    static var className: String {
+        return String(describing: self)
+    }
+}

+ 18 - 0
Libraries external/Sheeeeeeeeet/Extensions/UIView+Empty.swift

@@ -0,0 +1,18 @@
+//
+//  UIView+Empty.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2017-11-19.
+//  Copyright © 2017 Daniel Saidi. All rights reserved.
+//
+
+import UIKit
+
+extension UIView {
+
+    static var empty: UIView {
+        let view = UIView(frame: CGRect(x: 0, y: 0, width: 1, height: 1))
+        view.backgroundColor = UIColor.clear
+        return view
+    }
+}

+ 17 - 0
Libraries external/Sheeeeeeeeet/Extensions/UIViewController+RootViewController.swift

@@ -0,0 +1,17 @@
+//
+//  UIViewController+RootViewController.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2017-12-01.
+//  Copyright © 2017 Daniel Saidi. All rights reserved.
+//
+
+import UIKit
+
+extension UIViewController {
+
+    var rootViewController: UIViewController {
+        guard let parent = self.parent else { return self }
+        return parent.rootViewController
+    }
+}

+ 111 - 0
Libraries external/Sheeeeeeeeet/Items/ActionSheetItem.swift

@@ -0,0 +1,111 @@
+//
+//  ActionSheetItem.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2017-11-24.
+//  Copyright © 2017 Daniel Saidi. All rights reserved.
+//
+
+/*
+ 
+ This class represents a regular action sheet item, like the
+ ones used in UIAlertController. It has a title, an optional
+ value and an optional image. All other item classes inherit
+ this class.
+ 
+ The default tap behavior of action sheet items is "dismiss",
+ which means that the action sheet is told that the item was
+ tapped and is then dismissed. If you don't want the item to
+ dismiss the action sheet, set `tapBehavior` to `.none`.
+ 
+ An action sheet item's appearance is set by the sheet, when
+ it is presented. To use custom appearances for single items,
+ just modify the item's `appearance` property.
+ 
+ */
+
+import UIKit
+
+open class ActionSheetItem: NSObject {
+    
+    
+    // MARK: - Initialization
+    
+    public init(
+        title: String,
+        subtitle: String? = nil,
+        value: Any? = nil,
+        image: UIImage? = nil,
+        tapBehavior: TapBehavior = .dismiss) {
+        let appearance = ActionSheetAppearance.standard.item
+        self.title = title
+        self.subtitle = subtitle
+        self.value = value
+        self.image = image
+        self.tapBehavior = tapBehavior
+        self.appearance = ActionSheetItemAppearance(copy: appearance)
+        super.init()
+    }
+    
+    
+    // MARK: - Enums
+    
+    public enum ItemType {
+        case item, button, title
+    }
+    
+    public enum TapBehavior {
+        case dismiss, none
+    }
+
+
+    // MARK: - Properties
+    
+    public var cellReuseIdentifier: String { return className }
+    public var className: String { return type(of: self).className }
+    open var itemType: ItemType { return .item }
+    
+    open var image: UIImage?
+    open var subtitle: String?
+    open var title: String
+    open var value: Any?
+
+    open var appearance: ActionSheetItemAppearance
+    open var cellStyle: UITableViewCell.CellStyle = .default
+    open var customAppearance: ActionSheetItemAppearance?
+    open var tapBehavior: TapBehavior
+    
+    
+    // MARK: - Functions
+    
+    open func applyAppearance(_ appearance: ActionSheetAppearance) {
+        self.appearance = customAppearance ?? ActionSheetItemAppearance(copy: appearance.item)
+    }
+    
+    open func applyAppearance(to cell: UITableViewCell) {
+        if let color = appearance.backgroundColor {
+            cell.backgroundColor = color
+        }
+        cell.imageView?.image = image
+        cell.textLabel?.text = title
+        cell.selectionStyle = .default
+        cell.separatorInset = appearance.separatorInsets
+        cell.tintColor = appearance.tintColor
+        cell.textLabel?.textAlignment = .left
+        cell.textLabel?.textColor = appearance.textColor
+        cell.textLabel?.font = appearance.font
+        cell.detailTextLabel?.text = subtitle
+        cell.detailTextLabel?.font = appearance.subtitleFont
+        cell.detailTextLabel?.textColor = appearance.subtitleTextColor
+    }
+    
+    open func cell(for tableView: UITableView) -> UITableViewCell {
+        let id = cellReuseIdentifier
+        let cell = tableView.dequeueReusableCell(withIdentifier: id) as? ActionSheetItemCell
+            ?? ActionSheetItemCell(style: cellStyle, reuseIdentifier: id)
+        applyAppearance(to: cell)
+        return cell
+    }
+    
+    open func handleTap(in actionSheet: ActionSheet, cell: UITableViewCell? = nil) {}
+}

+ 44 - 0
Libraries external/Sheeeeeeeeet/Items/Buttons/ActionSheetButton.swift

@@ -0,0 +1,44 @@
+//
+//  ActionSheetButton.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2017-11-26.
+//  Copyright © 2017 Daniel Saidi. All rights reserved.
+//
+
+/*
+ 
+ This class is a base class for all action sheet buttons. It
+ is not intended to be used directly. Instead, use the built
+ in buttons or subclass this class to create your own button.
+ 
+ */
+
+import UIKit
+
+open class ActionSheetButton: ActionSheetItem {
+    
+    
+    // MARK: - Initialization
+    
+    public init(title: String, value: Bool?) {
+        super.init(title: title, value: value)
+    }
+    
+    
+    // MARK: - Properties
+    
+    open override var itemType: ItemType { return .button }
+    
+    
+    // MARK: - Functions
+    
+    open override func applyAppearance(_ appearance: ActionSheetAppearance) {
+        self.appearance = ActionSheetButtonAppearance(copy: appearance.okButton)
+    }
+    
+    open override func applyAppearance(to cell: UITableViewCell) {
+        super.applyAppearance(to: cell)
+        cell.textLabel?.textAlignment = .center
+    }
+}

+ 34 - 0
Libraries external/Sheeeeeeeeet/Items/Buttons/ActionSheetCancelButton.swift

@@ -0,0 +1,34 @@
+//
+//  ActionSheetCancelButton.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2017-11-26.
+//  Copyright © 2017 Daniel Saidi. All rights reserved.
+//
+
+/*
+ 
+ Cancel buttons have no special behavior, but can be used in
+ sheets where a user applies changes by tapping an OK button.
+ The default cancel button value is `nil`.
+ 
+ */
+
+import UIKit
+
+open class ActionSheetCancelButton: ActionSheetButton {
+    
+    
+    // MARK: - Initialization
+    
+    public init(title: String) {
+        super.init(title: title, value: nil)
+    }
+    
+    
+    // MARK: - Functions
+    
+    open override func applyAppearance(_ appearance: ActionSheetAppearance) {
+        self.appearance = ActionSheetCancelButtonAppearance(copy: appearance.cancelButton)
+    }
+}

+ 35 - 0
Libraries external/Sheeeeeeeeet/Items/Buttons/ActionSheetDangerButton.swift

@@ -0,0 +1,35 @@
+//
+//  ActionSheetDangerButton.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2017-11-27.
+//  Copyright © 2017 Daniel Saidi. All rights reserved.
+//
+
+/*
+ 
+ Danger buttons have no special behavior, but can be used to
+ indicate that the effect of the action sheet is destructive.
+ 
+ The value of a danger button is `true` by default.
+ 
+ */
+
+import UIKit
+
+open class ActionSheetDangerButton: ActionSheetButton {
+    
+    
+    // MARK: - Initialization
+    
+    public init(title: String) {
+        super.init(title: title, value: true)
+    }
+    
+    
+    // MARK: - Functions
+    
+    open override func applyAppearance(_ appearance: ActionSheetAppearance) {
+        self.appearance = ActionSheetDangerButtonAppearance(copy: appearance.dangerButton)
+    }
+}

+ 35 - 0
Libraries external/Sheeeeeeeeet/Items/Buttons/ActionSheetOkButton.swift

@@ -0,0 +1,35 @@
+//
+//  ActionSheetOkButton.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2017-11-26.
+//  Copyright © 2017 Daniel Saidi. All rights reserved.
+//
+
+/*
+ 
+ OK buttons have no special behavior, but can be used when a
+ user should apply action sheet changes by tapping an button.
+ 
+ The value of an OK button is `true` by default.
+ 
+ */
+
+import UIKit
+
+open class ActionSheetOkButton: ActionSheetButton {
+    
+    
+    // MARK: - Initialization
+    
+    public init(title: String) {
+        super.init(title: title, value: true)
+    }
+    
+    
+    // MARK: - Functions
+    
+    open override func applyAppearance(_ appearance: ActionSheetAppearance) {
+        self.appearance = ActionSheetOkButtonAppearance(copy: appearance.okButton)
+    }
+}

+ 130 - 0
Libraries external/Sheeeeeeeeet/Items/Items/ActionSheetCollectionItem.swift

@@ -0,0 +1,130 @@
+//
+//  ActionSheetCollectionItem.swift
+//  Sheeeeeeeeet
+//
+//  Created by Jonas Ullström (ullstrm) on 2018-03-01.
+//  Copyright © 2018 Jonas Ullström. All rights reserved.
+//
+
+/*
+ 
+ Collection items can be used to present item collections in
+ a collection view, using cell types that you define in your
+ project and implement `ActionSheetCollectionItemContentCell`.
+ The cell `.xib` should have the same name as the cell class.
+ 
+ This class will dequeue a different cell type than standard
+ action sheet items. If you look at `cell(for: ...)`, you'll
+ see that it uses `ActionSheetCollectionItemCell` for its id.
+ 
+ */
+
+import Foundation
+
+open class ActionSheetCollectionItem<T>: ActionSheetItem, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout where T: ActionSheetCollectionItemContentCell {
+    
+    
+    // MARK: - Initialization
+    
+    public init(
+        itemCellType: T.Type,
+        itemCount: Int,
+        setupAction: @escaping CellAction,
+        selectionAction: @escaping CellAction) {
+        self.itemCellType = itemCellType
+        self.itemCount = itemCount
+        self.setupAction = setupAction
+        self.selectionAction = selectionAction
+        super.init(title: "")
+    }
+    
+    
+    // MARK: - Typealiases
+    
+    public typealias CellAction = (_ cell: T, _ index: Int) -> ()
+    
+    
+    // MARK: - Properties
+    
+    public let itemCellType: T.Type
+    public let itemCount: Int
+    public private(set) var selectionAction: CellAction
+    public let setupAction: CellAction
+    
+    
+    // MARK: - Functions
+    
+    open override func applyAppearance(_ appearance: ActionSheetAppearance) {
+        super.applyAppearance(appearance)
+        self.appearance = ActionSheetCollectionItemAppearance(copy: appearance.collectionItem)
+        self.appearance.height = T.defaultSize.height + T.topInset + T.bottomInset + 0.5
+    }
+    
+    open override func applyAppearance(to cell: UITableViewCell) {
+        super.applyAppearance(to: cell)
+        guard let itemCell = cell as? ActionSheetCollectionItemCell else { return }
+        itemCell.setup(withNib: T.nib, owner: self)
+    }
+    
+    open override func cell(for tableView: UITableView) -> UITableViewCell {
+        tableView.register(ActionSheetCollectionItemCell.nib, forCellReuseIdentifier: cellReuseIdentifier)
+        return super.cell(for: tableView)
+    }
+    
+    open func extendSelectionAction(toReload actionSheet: ActionSheet) {
+        weak var sheet = actionSheet
+        extendSelectionAction(with: { _, _ in
+            sheet?.reloadData()
+        })
+    }
+    
+    open func extendSelectionAction(with action: @escaping CellAction) {
+        let currentSelectionAction = selectionAction
+        selectionAction = { cell, index in
+            currentSelectionAction(cell, index)
+            action(cell, index)
+        }
+    }
+    
+    
+    // MARK: - UICollectionViewDataSource
+    
+    open func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
+        return itemCount
+    }
+    
+    open func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
+        let id = ActionSheetCollectionItemCell.itemCellIdentifier
+        let dequeued = collectionView.dequeueReusableCell(withReuseIdentifier: id, for: indexPath)
+        guard let cell = dequeued as? T else { return UICollectionViewCell() }
+        setupAction(cell, indexPath.row)
+        return cell
+    }
+    
+    
+    // MARK: - UICollectionViewDelegate
+    
+    open func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
+        guard let cell = collectionView.cellForItem(at: indexPath) as? T else { return }
+        selectionAction(cell, indexPath.row)
+    }
+    
+    
+    // MARK: - FlowLayout delegate
+    
+    open func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
+        return T.defaultSize
+    }
+    
+    open func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
+        return UIEdgeInsets(top: T.topInset, left: T.leftInset, bottom: T.bottomInset, right: T.rightInset)
+    }
+    
+    open func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
+        return T.itemSpacing
+    }
+    
+    open func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
+        return 0
+    }
+}

+ 64 - 0
Libraries external/Sheeeeeeeeet/Items/Items/ActionSheetCustomItem.swift

@@ -0,0 +1,64 @@
+//
+//  ActionSheetCustomViewItem.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2018-10-08.
+//  Copyright © 2018 Daniel Saidi. All rights reserved.
+//
+
+/*
+ 
+ Custom items can be used to present any view in your sheets.
+ Just specify the view type you want to use and make sure it
+ inherits `ActionSheetItemCell`, and that it also implements
+ `ActionSheetCustomItemCell`.
+ 
+ */
+
+import UIKit
+
+public class ActionSheetCustomItem<T>: ActionSheetItem where T: ActionSheetCustomItemCell {
+    
+    
+    // MARK: - Initialization
+    
+    public init(cellType: T.Type, setupAction: @escaping SetupAction) {
+        self.cellType = cellType
+        self.setupAction = setupAction
+        super.init(
+            title: "",
+            subtitle: nil,
+            value: nil,
+            image: nil,
+            tapBehavior: .none)
+    }
+    
+    
+    // MARK: - Typealiases
+    
+    public typealias SetupAction = (_ cell: T) -> ()
+    
+    
+    // MARK: - Properties
+    
+    public let cellType: T.Type
+    public let setupAction: SetupAction
+    
+    
+    // MARK: - Functions
+    
+    public override func applyAppearance(_ appearance: ActionSheetAppearance) {
+        super.applyAppearance(appearance)
+        self.appearance = ActionSheetCustomItemAppearance(copy: appearance.customItem)
+        self.appearance.height = T.defaultSize.height
+    }
+    
+    open override func cell(for tableView: UITableView) -> UITableViewCell {
+        tableView.register(T.nib, forCellReuseIdentifier: cellReuseIdentifier)
+        let cell = super.cell(for: tableView)
+        cell.selectionStyle = .none
+        guard let typedCell = cell as? T else { fatalError("Invalid cell type created by superclass") }
+        setupAction(typedCell)
+        return typedCell
+    }
+}

+ 40 - 0
Libraries external/Sheeeeeeeeet/Items/Items/ActionSheetLinkItem.swift

@@ -0,0 +1,40 @@
+//
+//  ActionSheetLinkItem.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2017-11-26.
+//  Copyright © 2017 Daniel Saidi. All rights reserved.
+//
+
+/*
+ 
+ Link items can be used when tapping them will take the user
+ somewhere, e.g. to another view controller or a web site.
+ 
+ */
+
+import UIKit
+
+open class ActionSheetLinkItem: ActionSheetItem {
+    
+    
+    // MARK: - Properties
+    
+    open var linkAppearance: ActionSheetLinkItemAppearance? {
+        return appearance as? ActionSheetLinkItemAppearance
+    }
+    
+    
+    // MARK: - Functions
+    
+    open override func applyAppearance(_ appearance: ActionSheetAppearance) {
+        super.applyAppearance(appearance)
+        self.appearance = ActionSheetLinkItemAppearance(copy: appearance.linkItem)
+    }
+    
+    open override func applyAppearance(to cell: UITableViewCell) {
+        super.applyAppearance(to: cell)
+        guard let appearance = linkAppearance else { return }
+        cell.accessoryView = UIImageView(image: appearance.linkIcon)
+    }
+}

+ 62 - 0
Libraries external/Sheeeeeeeeet/Items/Items/ActionSheetMultiSelectItem.swift

@@ -0,0 +1,62 @@
+//
+//  ActionSheetMultiSelectItem.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2018-03-31.
+//  Copyright © 2018 Daniel Saidi. All rights reserved.
+//
+
+/*
+ 
+ `ActionSheetMultiSelectItem` should be used whenever a user
+ should be able to select one or several items in a sheet. A
+ multi select item will not affect other items, and will not
+ dismiss the sheet.
+ 
+ Multi-select items can be used in combination with a toggle
+ item (`ActionSheetMultiSelectToggleItem`), which can toggle
+ the selected state of all items in the same group.
+ 
+ A multi-select item does not dismiss the sheet, since users
+ will most probably be in a context where a change should be
+ applied with an OK button.
+ 
+ */
+
+import UIKit
+
+open class ActionSheetMultiSelectItem: ActionSheetSelectItem {
+    
+    
+    // MARK: - Initialization
+    
+    public init(
+        title: String,
+        isSelected: Bool,
+        group: String = "",
+        value: Any? = nil,
+        image: UIImage? = nil) {
+        super.init(
+            title: title,
+            isSelected: isSelected,
+            group: group,
+            value: value,
+            image: image,
+            tapBehavior: .none)
+    }
+    
+    
+    // MARK: - Functions
+    
+    open override func applyAppearance(_ appearance: ActionSheetAppearance) {
+        super.applyAppearance(appearance)
+        self.appearance = ActionSheetMultiSelectItemAppearance(copy: appearance.multiSelectItem)
+    }
+    
+    open override func handleTap(in actionSheet: ActionSheet, cell: UITableViewCell? = nil) {
+        super.handleTap(in: actionSheet, cell: cell)
+        let toggleItems = actionSheet.items.compactMap { $0 as? ActionSheetMultiSelectToggleItem }
+        let items = toggleItems.filter { $0.group == group }
+        items.forEach { $0.updateState(for: actionSheet) }
+    }
+}

+ 86 - 0
Libraries external/Sheeeeeeeeet/Items/Items/ActionSheetMultiSelectToggleItem.swift

@@ -0,0 +1,86 @@
+//
+//  ActionSheetMultiSelectToggleItem.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2018-03-31.
+//  Copyright © 2018 Daniel Saidi. All rights reserved.
+//
+
+/*
+ 
+ Multi-select toggle items can be used together with a group
+ of `ActionSheetMultiSelectItem`s. When tapped, it will make
+ all multi-select items in the same group select/deselect.
+ 
+ Since this item must know about the multi-select items when
+ setting its select/deselect title text, you must provide it
+ with an initial `State` when creating it. After that, it is
+ able to update itself whenever it is tapped.
+ 
+ */
+
+import UIKit
+
+open class ActionSheetMultiSelectToggleItem: ActionSheetItem {
+    
+    
+    // MARK: - Initialization
+    
+    public init(title: String, state: State, group: String, selectAllTitle: String, deselectAllTitle: String) {
+        self.group = group
+        self.state = state
+        self.deselectAllTitle = deselectAllTitle
+        self.selectAllTitle = selectAllTitle
+        super.init(
+            title: title,
+            tapBehavior: .none)
+        cellStyle = .value1
+    }
+    
+    
+    // MARK: - State
+    
+    public enum State {
+        case selectAll, deselectAll
+    }
+    
+    
+    // MARK: - Properties
+    
+    open var deselectAllTitle: String
+    open var group: String
+    open var selectAllTitle: String
+    open var state: State
+    
+    
+    // MARK: - Functions
+    
+    open override func applyAppearance(_ appearance: ActionSheetAppearance) {
+        super.applyAppearance(appearance)
+        self.appearance = ActionSheetMultiSelectToggleItemAppearance(copy: appearance.multiSelectToggleItem)
+    }
+    
+    open override func applyAppearance(to cell: UITableViewCell) {
+        super.applyAppearance(to: cell)
+        guard let appearance = appearance as? ActionSheetMultiSelectToggleItemAppearance else { return }
+        let isSelectAll = state == .selectAll
+        subtitle = isSelectAll ? selectAllTitle : deselectAllTitle
+        appearance.subtitleTextColor = isSelectAll ? appearance.selectAllTextColor : appearance.deselectAllTextColor
+        super.applyAppearance(to: cell)
+    }
+    
+    open override func handleTap(in actionSheet: ActionSheet, cell: UITableViewCell? = nil) {
+        super.handleTap(in: actionSheet)
+        let selectItems = actionSheet.items.compactMap { $0 as? ActionSheetMultiSelectItem }
+        let items = selectItems.filter { $0.group == group }
+        let shouldSelectAll = items.contains { !$0.isSelected }
+        items.forEach { $0.isSelected = shouldSelectAll ? true : false }
+        updateState(for: actionSheet)
+    }
+    
+    open func updateState(for actionSheet: ActionSheet) {
+        let selectItems = actionSheet.items.compactMap { $0 as? ActionSheetMultiSelectItem }
+        let items = selectItems.filter { $0.group == group }
+        state = items.contains { !$0.isSelected } ? .selectAll : .deselectAll
+    }
+}

+ 82 - 0
Libraries external/Sheeeeeeeeet/Items/Items/ActionSheetSelectItem.swift

@@ -0,0 +1,82 @@
+//
+//  ActionSheetSelectItem.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2017-11-26.
+//  Copyright © 2017 Daniel Saidi. All rights reserved.
+//
+
+/*
+ 
+ Select items are used to let the user select one or several
+ items in an action sheet. Unlike the `ActionSheetItem` type,
+ this type has an `isSelected` state, a selected icon and an
+ extended appearance.
+ 
+ This item type is not meant to be used directly. However, a
+ `selectItem` appearance property is still available, so you
+ can style single and multiselect items in a single way.
+ 
+ Instead of this type, you should use any of its subclasses:
+ 
+ * `ActionSheetSingleSelectItem`
+ * `ActionSheetMultiSelectItem`
+ 
+ */
+
+import UIKit
+
+open class ActionSheetSelectItem: ActionSheetItem {
+    
+    
+    // MARK: - Initialization
+    
+    init(
+        title: String,
+        isSelected: Bool,
+        group: String = "",
+        value: Any? = nil,
+        image: UIImage? = nil,
+        tapBehavior: TapBehavior = .dismiss) {
+        self.isSelected = isSelected
+        self.group = group
+        super.init(
+            title: title,
+            value: value,
+            image: image,
+            tapBehavior: tapBehavior)
+    }
+    
+    
+    // MARK: - Properties
+    
+    open var group: String
+    
+    open var isSelected: Bool
+    
+    open var selectAppearance: ActionSheetSelectItemAppearance? {
+        return appearance as? ActionSheetSelectItemAppearance
+    }
+    
+    
+    // MARK: - Functions
+    
+    open override func applyAppearance(_ appearance: ActionSheetAppearance) {
+        super.applyAppearance(appearance)
+        self.appearance = ActionSheetSelectItemAppearance(copy: appearance.selectItem)
+    }
+    
+    open override func applyAppearance(to cell: UITableViewCell) {
+        super.applyAppearance(to: cell)
+        guard let appearance = selectAppearance else { return }
+        cell.accessoryView = isSelected ? UIImageView(image: appearance.selectedIcon) : nil
+        cell.accessoryView?.tintColor = isSelected ? appearance.selectedIconTintColor : appearance.tintColor
+        cell.tintColor = isSelected ? appearance.selectedTintColor : appearance.tintColor
+        cell.textLabel?.textColor = isSelected ? appearance.selectedTextColor : appearance.textColor
+    }
+    
+    open override func handleTap(in actionSheet: ActionSheet, cell: UITableViewCell? = nil) {
+        super.handleTap(in: actionSheet, cell: cell)
+        isSelected = !isSelected
+    }
+}

+ 57 - 0
Libraries external/Sheeeeeeeeet/Items/Items/ActionSheetSingleSelectItem.swift

@@ -0,0 +1,57 @@
+//
+//  ActionSheetSingleSelectItem.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2018-03-12.
+//  Copyright © 2018 Daniel Saidi. All rights reserved.
+//
+
+/*
+ 
+ `ActionSheetSingleSelectItem` should be used whenever users
+ should only be able to select a single item in a sheet or a
+ group. It automatically deselects other single select items
+ in the same group. You can have several groups in one sheet.
+ 
+ A single select item will dismiss the sheet when tapped. To
+ change this behavior, set `tapBehavior` to `.none`.
+ 
+ */
+
+import UIKit
+
+open class ActionSheetSingleSelectItem: ActionSheetSelectItem {
+    
+    
+    // MARK: - Initialization
+    
+    public init(
+        title: String,
+        isSelected: Bool,
+        group: String = "",
+        value: Any? = nil,
+        image: UIImage? = nil) {
+        super.init(
+            title: title,
+            isSelected: isSelected,
+            group: group,
+            value: value,
+            image: image)
+    }
+    
+    
+     // MARK: - Functions
+    
+    open override func applyAppearance(_ appearance: ActionSheetAppearance) {
+        super.applyAppearance(appearance)
+        self.appearance = ActionSheetSingleSelectItemAppearance(copy: appearance.singleSelectItem)
+    }
+    
+    open override func handleTap(in actionSheet: ActionSheet, cell: UITableViewCell? = nil) {
+        super.handleTap(in: actionSheet, cell: cell)
+        let items = actionSheet.items.compactMap { $0 as? ActionSheetSingleSelectItem }
+        let deselectItems = items.filter { $0.group == group }
+        deselectItems.forEach { $0.isSelected = false }
+        isSelected = true
+    }
+}

+ 44 - 0
Libraries external/Sheeeeeeeeet/Items/Titles/ActionSheetSectionMargin.swift

@@ -0,0 +1,44 @@
+//
+//  ActionSheetSectionMargin.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2017-11-27.
+//  Copyright © 2017 Daniel Saidi. All rights reserved.
+//
+
+/*
+ 
+ Section margins items can be used to add additional spacing
+ before new sections. They are not selectable, but will send
+ a tap event to the action sheet in which they are used.
+ 
+ */
+
+import UIKit
+
+open class ActionSheetSectionMargin: ActionSheetItem {
+    
+    
+    // MARK: - Initialization
+    
+    public init() {
+        super.init(title: "", tapBehavior: .none)
+    }
+    
+    
+    // MARK: - Properties
+    
+    open override var itemType: ItemType { return .title }
+    
+    
+    // MARK: - Functions
+    
+    open override func applyAppearance(_ appearance: ActionSheetAppearance) {
+        self.appearance = ActionSheetSectionMarginAppearance(copy: appearance.sectionMargin)
+    }
+    
+    open override func applyAppearance(to cell: UITableViewCell) {
+        super.applyAppearance(to: cell)
+        cell.selectionStyle = .none
+    }
+}

+ 49 - 0
Libraries external/Sheeeeeeeeet/Items/Titles/ActionSheetSectionTitle.swift

@@ -0,0 +1,49 @@
+//
+//  ActionSheetSectionTitle.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2017-11-26.
+//  Copyright © 2017 Daniel Saidi. All rights reserved.
+//
+
+/*
+ 
+ Section title items can be used to segment action sheets in
+ sections. They serve no purpose beyond to visually indicate
+ that certain items belong together. A section item can have
+ a title and a subtitle.
+ 
+ To add additional space above a section title, make sure to
+ add a `ActionSheetSectionMargin` before the section title.
+ 
+ */
+
+import UIKit
+
+open class ActionSheetSectionTitle: ActionSheetItem {
+    
+    
+    // MARK: - Initialization
+    
+    public init(title: String, subtitle: String? = nil) {
+        super.init(title: title, subtitle: subtitle, tapBehavior: .none)
+        cellStyle = .value1
+    }
+    
+    
+    // MARK: - Properties
+    
+    open override var itemType: ItemType { return .title }
+    
+    
+    // MARK: - Functions
+    
+    open override func applyAppearance(_ appearance: ActionSheetAppearance) {
+        self.appearance = ActionSheetSectionTitleAppearance(copy: appearance.sectionTitle)
+    }
+    
+    open override func applyAppearance(to cell: UITableViewCell) {
+        super.applyAppearance(to: cell)
+        cell.selectionStyle = .none
+    }
+}

+ 45 - 0
Libraries external/Sheeeeeeeeet/Items/Titles/ActionSheetTitle.swift

@@ -0,0 +1,45 @@
+//
+//  ActionSheetTitle.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2017-11-26.
+//  Copyright © 2017 Daniel Saidi. All rights reserved.
+//
+
+/*
+ 
+ Title items can be used to add main titles to action sheets.
+ They are not selectable, but will still send a tap event to
+ the action sheet in which they are used.
+ 
+ */
+
+import UIKit
+
+open class ActionSheetTitle: ActionSheetItem {
+    
+    
+    // MARK: - Initialization
+    
+    public init(title: String) {
+        super.init(title: title, tapBehavior: .none)
+    }
+    
+    
+    // MARK: - Properties
+    
+    open override var itemType: ItemType { return .title }
+    
+    
+    // MARK: - Functions
+    
+    open override func applyAppearance(_ appearance: ActionSheetAppearance) {
+        self.appearance = ActionSheetTitleAppearance(copy: appearance.title)
+    }
+    
+    open override func applyAppearance(to cell: UITableViewCell) {
+        super.applyAppearance(to: cell)
+        cell.selectionStyle = .none
+        cell.textLabel?.textAlignment = .center
+    }
+}

+ 151 - 0
Libraries external/Sheeeeeeeeet/Presenters/ActionSheetDefaultPresenter.swift

@@ -0,0 +1,151 @@
+//
+//  ActionSheetDefaultPresenter.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2017-11-27.
+//  Copyright © 2017 Daniel Saidi. All rights reserved.
+//
+
+/*
+ 
+ This presenter will present action sheets as regular action
+ sheets, which means that it presents sheets from the bottom.
+ 
+ */
+
+import UIKit
+
+open class ActionSheetDefaultPresenter: ActionSheetPresenter {
+    
+    
+    // MARK: - Initialization
+    
+    public init() {}
+    
+    deinit { print("\(type(of: self)) deinit") }
+    
+    
+    // MARK: - Properties
+    
+    open var availablePresentationSize: CGSize { return UIScreen.main.bounds.size }
+    open var events = ActionSheetPresenterEvents()
+    open var isDismissableWithTapOnBackground = true
+    
+    private var actionSheet: ActionSheet?
+    private var actionSheetView: UIView?
+    private var backgroundColor = UIColor.black.withAlphaComponent(0.4)
+    private var backgroundView: UIView?
+    
+    
+    // MARK: - ActionSheetPresenter
+    
+    open func dismiss(completion: @escaping () -> ()) {
+        dismissActionSheet()
+        completion()
+    }
+    
+    open func present(sheet: ActionSheet, in vc: UIViewController, from view: UIView?) {
+        present(sheet: sheet, in: vc)
+    }
+    
+    open func present(sheet: ActionSheet, in vc: UIViewController, from item: UIBarButtonItem) {
+        present(sheet: sheet, in: vc)
+    }
+    
+    open func present(sheet: ActionSheet, in vc: UIViewController) {
+        actionSheet = sheet
+        addBackgroundView(to: vc.view)
+        addActionSheetView(from: sheet, to: vc.view)
+        presentBackgroundView()
+        presentActionSheet(sheet, in: vc.view)
+    }
+    
+    
+    // MARK: - Protected, overridable Functions
+    
+    open func addActionSheetView(from sheet: ActionSheet, to view: UIView) {
+        guard let sheetView = sheet.view else { return }
+        sheetView.frame.size.height = sheet.contentHeight
+        view.addSubview(sheetView)
+        actionSheetView = sheetView
+    }
+    
+    open func addBackgroundView(to view: UIView) {
+        let bgView = UIView(frame: view.frame)
+        bgView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+        addBackgroundViewTapAction(to: bgView)
+        view.addSubview(bgView)
+        bgView.backgroundColor = backgroundColor
+        backgroundView = bgView
+    }
+    
+    open func addBackgroundViewTapAction(to view: UIView) {
+        view.isUserInteractionEnabled = true
+        let action = #selector(backgroundViewTapAction)
+        let tap = UITapGestureRecognizer(target: self, action: action)
+        view.addGestureRecognizer(tap)
+    }
+    
+    open func animate(_ animation: @escaping () -> ()) {
+        animate(animation, completion: nil)
+    }
+    
+    open func animate(_ animation: @escaping () -> (), completion: (() -> ())?) {
+        UIView.animate(withDuration: 0.3, delay: 0, options: [.curveEaseOut], animations: animation) { _ in completion?() }
+    }
+    
+    open func dismissActionSheet() {
+        actionSheet = nil
+        removeActionSheetView()
+        removeBackgroundView()
+    }
+    
+    open func presentActionSheet(_ sheet: ActionSheet, in view: UIView) {
+        guard let sheetView = actionSheetView else { return }
+        sheetView.frame = presentationTransitionStartFrame(for: sheet, in: view)
+        animate { sheetView.frame = self.presentationFrame(for: sheet, in: view) ?? .zero }
+        sheetView.autoresizingMask = [.flexibleWidth, .flexibleTopMargin]
+    }
+    
+    open func presentationFrame(for sheet: ActionSheet, in view: UIView) -> CGRect? {
+        return sheet.bottomPresentationFrame
+    }
+    
+    open func presentationTransitionStartFrame(for sheet: ActionSheet, in view: UIView) -> CGRect {
+        var frame = presentationFrame(for: sheet, in: view) ?? .zero
+        frame.origin.y += 100
+        return frame
+    }
+    
+    open func presentBackgroundView() {
+        guard let view = backgroundView else { return }
+        view.alpha = 0
+        animate { view.alpha = 1 }
+    }
+    
+    open func removeActionSheetView() {
+        guard let view = actionSheetView else { return }
+        var frame = view.frame
+        frame.origin.y += frame.height + 100
+        let animation = { view.frame = frame }
+        animate(animation) { view.removeFromSuperview() }
+    }
+    
+    open func removeBackgroundView() {
+        guard let view = backgroundView else { return }
+        let animation = { view.alpha = 0 }
+        animate(animation) { view.removeFromSuperview() }
+    }
+}
+
+
+// MARK: - Actions
+
+@objc public extension ActionSheetDefaultPresenter {
+    
+    public func backgroundViewTapAction() {
+        guard isDismissableWithTapOnBackground else { return }
+        events.didDismissWithBackgroundTap?()
+        dismissActionSheet()
+    }
+}

+ 112 - 0
Libraries external/Sheeeeeeeeet/Presenters/ActionSheetPopoverPresenter.swift

@@ -0,0 +1,112 @@
+//
+//  ActionSheetPopoverPresenter.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2017-11-24.
+//  Copyright © 2017 Daniel Saidi. All rights reserved.
+//
+
+/*
+ 
+ This presenter will present action sheets as popovers, just
+ as regular UIAlertControllers are displayed on the iPad. It
+ should only be used when a sheet is displayed on an iPad.
+ 
+ Since popovers have an arrow that should use the same color
+ as the rest of the popover view, this presenter will remove
+ any header view as well as combine items and buttons into a
+ single section.
+ 
+ */
+
+import UIKit
+
+open class ActionSheetPopoverPresenter: NSObject, ActionSheetPresenter {
+    
+    
+    // MARK: - Initialization
+    
+    deinit { print("\(type(of: self)) deinit") }
+    
+    
+    // MARK: - Properties
+    
+    open var availablePresentationSize: CGSize { return popover?.frameOfPresentedViewInContainerView.size ?? .zero }
+    open var events = ActionSheetPresenterEvents()
+    open var isDismissableWithTapOnBackground = true
+    
+    private var actionSheet: ActionSheet?
+    private var actionSheetView: UIView?
+    private var backgroundView: UIView?
+    private weak var popover: UIPopoverPresentationController?
+    
+    
+    // MARK: - ActionSheetPresenter
+    
+    public func dismiss(completion: @escaping () -> ()) {
+        let dismissAction = { completion();  self.actionSheet = nil }
+        let vc = actionSheet?.presentingViewController
+        vc?.dismiss(animated: true) { dismissAction() } ?? dismissAction()
+    }
+    
+    open func present(sheet: ActionSheet, in vc: UIViewController, from view: UIView?) {
+        popover = self.popover(for: sheet, in: vc)
+        popover?.sourceView = view
+        popover?.sourceRect = view?.bounds ?? CGRect()
+        popover?.delegate = self
+        vc.present(sheet, animated: true, completion: nil)
+    }
+    
+    open func present(sheet: ActionSheet, in vc: UIViewController, from item: UIBarButtonItem) {
+        popover = self.popover(for: sheet, in: vc)
+        popover?.barButtonItem = item
+        vc.present(sheet, animated: true, completion: nil)
+    }
+    
+    public func presentationFrame(for sheet: ActionSheet, in view: UIView) -> CGRect? {
+        return nil
+    }
+}
+
+
+// MARK: - UIPopoverPresentationControllerDelegate
+
+extension ActionSheetPopoverPresenter: UIPopoverPresentationControllerDelegate {
+    
+    public func popoverPresentationControllerShouldDismissPopover(_ controller: UIPopoverPresentationController) -> Bool {
+        guard isDismissableWithTapOnBackground else { return false }
+        events.didDismissWithBackgroundTap?()
+        dismiss {}
+        return false
+    }
+}
+
+
+// MARK: - Private Functions
+
+private extension ActionSheetPopoverPresenter {
+    
+    func popover(for sheet: ActionSheet, in vc: UIViewController) -> UIPopoverPresentationController? {
+        guard sheet.contentHeight > 0 else { return nil }
+        setupSheetForPresentation(sheet)
+        sheet.modalPresentationStyle = .popover
+        let popover = sheet.popoverPresentationController
+        popover?.backgroundColor = sheet.view.backgroundColor
+        popover?.delegate = vc as? UIPopoverPresentationControllerDelegate
+        return popover
+    }
+    
+    func popoverItems(for sheet: ActionSheet) -> [ActionSheetItem] {
+        let items: [ActionSheetItem] = sheet.items + sheet.buttons
+        return items.filter { !($0 is ActionSheetCancelButton) }
+    }
+    
+    func setupSheetForPresentation(_ sheet: ActionSheet) {
+        self.actionSheet = sheet
+        sheet.headerView = nil
+        sheet.items = popoverItems(for: sheet)
+        sheet.buttons = []
+        sheet.preferredContentSize = sheet.preferredPopoverSize
+        sheet.view.backgroundColor = sheet.itemsView.backgroundColor
+    }
+}

+ 43 - 0
Libraries external/Sheeeeeeeeet/Presenters/ActionSheetPresenter.swift

@@ -0,0 +1,43 @@
+//
+//  ActionSheetPresenter.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2017-11-18.
+//  Copyright © 2017 Daniel Saidi. All rights reserved.
+//
+
+/*
+ 
+ Action sheet presenters are used by Sheeeeeeeeet to present
+ action sheets in different ways, e.g. with a default bottom
+ slide, showing a popover from the tapped view etc.
+ 
+ When implementing this protocol, `present(in:from:)` is the
+ standard way to present an action sheet, while `dismiss` is
+ the standard way to dismiss it.
+ 
+ `isDismissableWithTapOnBackground` is used to specify if an
+ action sheet can be dismissed by tapping on the background.
+ 
+ */
+
+import Foundation
+
+public struct ActionSheetPresenterEvents {
+    
+    public init() {}
+    
+    public var didDismissWithBackgroundTap: (() -> ())?
+}
+
+public protocol ActionSheetPresenter: AnyObject {
+    
+    var availablePresentationSize: CGSize { get }
+    var events: ActionSheetPresenterEvents { get set }
+    var isDismissableWithTapOnBackground: Bool { get set }
+    
+    func dismiss(completion: @escaping () -> ())
+    func present(sheet: ActionSheet, in vc: UIViewController, from view: UIView?)
+    func present(sheet: ActionSheet, in vc: UIViewController, from item: UIBarButtonItem)
+    func presentationFrame(for sheet: ActionSheet, in view: UIView) -> CGRect?
+}

+ 19 - 0
Libraries external/Sheeeeeeeeet/Sheeeeeeeeet.h

@@ -0,0 +1,19 @@
+//
+//  Sheeeeeeeeet.h
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2017-11-18.
+//  Copyright © 2017 Daniel Saidi. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+//! Project version number for Sheeeeeeeeet.
+FOUNDATION_EXPORT double SheeeeeeeeetVersionNumber;
+
+//! Project version string for Sheeeeeeeeet.
+FOUNDATION_EXPORT const unsigned char SheeeeeeeeetVersionString[];
+
+// In this header, you should import all the public headers of your framework using statements like #import <Sheeeeeeeeet/PublicHeader.h>
+
+

+ 34 - 0
Libraries external/Sheeeeeeeeet/Views/ActionSheetCollectionItemCell.swift

@@ -0,0 +1,34 @@
+import Foundation
+
+open class ActionSheetCollectionItemCell: ActionSheetItemCell {
+    
+    
+    // MARK: - Properties
+    
+    static var itemCellIdentifier: String { return "Cell" }
+    
+    static var nib: UINib = UINib(nibName: "ActionSheetCollectionItemCell", bundle: Bundle.init(for: ActionSheetCollectionItemCell.self))
+    
+    
+    // MARK: - Outlets
+    
+    @IBOutlet weak var collectionView: UICollectionView! {
+        didSet {
+            let flow = UICollectionViewFlowLayout()
+            flow.scrollDirection = .horizontal
+            collectionView.collectionViewLayout = flow
+        }
+    }
+    
+    
+    // MARK: - Functions
+    
+    func setup(withNib nib: UINib, owner: UICollectionViewDataSource & UICollectionViewDelegate) {
+        let id = ActionSheetCollectionItemCell.itemCellIdentifier
+        collectionView.contentInset = .zero
+        collectionView.register(nib, forCellWithReuseIdentifier: id)
+        collectionView.dataSource = owner
+        collectionView.delegate = owner
+        collectionView.reloadData()
+    }
+}

+ 46 - 0
Libraries external/Sheeeeeeeeet/Views/ActionSheetCollectionItemCell.xib

@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+    <device id="retina4_7" orientation="portrait">
+        <adaptation id="fullscreen"/>
+    </device>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" rowHeight="196" id="moX-qQ-Gyn" customClass="ActionSheetCollectionItemCell" customModule="Sheeeeeeeeet" customModuleProvider="target">
+            <rect key="frame" x="0.0" y="0.0" width="452" height="196"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="moX-qQ-Gyn" id="qre-fe-O26">
+                <rect key="frame" x="0.0" y="0.0" width="452" height="195.5"/>
+                <autoresizingMask key="autoresizingMask"/>
+                <subviews>
+                    <collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" dataMode="none" translatesAutoresizingMaskIntoConstraints="NO" id="eSV-yW-MpO">
+                        <rect key="frame" x="0.0" y="0.0" width="452" height="195.5"/>
+                        <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                        <collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="10" minimumInteritemSpacing="10" id="UCY-qV-avs">
+                            <size key="itemSize" width="50" height="50"/>
+                            <size key="headerReferenceSize" width="0.0" height="0.0"/>
+                            <size key="footerReferenceSize" width="0.0" height="0.0"/>
+                            <inset key="sectionInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/>
+                        </collectionViewFlowLayout>
+                    </collectionView>
+                </subviews>
+                <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                <constraints>
+                    <constraint firstAttribute="bottom" secondItem="eSV-yW-MpO" secondAttribute="bottom" id="Dnr-ur-bHp"/>
+                    <constraint firstAttribute="trailing" secondItem="eSV-yW-MpO" secondAttribute="trailing" id="Hbt-ZB-Gy8"/>
+                    <constraint firstItem="eSV-yW-MpO" firstAttribute="top" secondItem="qre-fe-O26" secondAttribute="top" id="OuY-7J-7R1"/>
+                    <constraint firstItem="eSV-yW-MpO" firstAttribute="leading" secondItem="qre-fe-O26" secondAttribute="leading" id="h5Z-mf-v8W"/>
+                </constraints>
+            </tableViewCellContentView>
+            <connections>
+                <outlet property="collectionView" destination="eSV-yW-MpO" id="s1m-Z2-HwO"/>
+            </connections>
+            <point key="canvasLocation" x="-28" y="-15"/>
+        </tableViewCell>
+    </objects>
+</document>

+ 27 - 0
Libraries external/Sheeeeeeeeet/Views/ActionSheetCollectionItemContentCell.swift

@@ -0,0 +1,27 @@
+//
+//  ActionSheetCollectionItemContentCell.swift
+//  Sheeeeeeeeet
+//
+//  Created by Jonas Ullström (ullstrm) on 2018-03-01.
+//  Copyright © 2018 Jonas Ullström. All rights reserved.
+//
+
+/*
+ 
+ This protocol must be implemented by any cell that is to be
+ used together with an `ActionSheetCollectionItem`.
+ 
+ */
+
+import UIKit
+
+public protocol ActionSheetCollectionItemContentCell where Self: UICollectionViewCell {
+    
+    static var nib: UINib { get }
+    static var defaultSize: CGSize { get }
+    static var leftInset: CGFloat { get }
+    static var rightInset: CGFloat { get }
+    static var topInset: CGFloat { get }
+    static var bottomInset: CGFloat { get }
+    static var itemSpacing: CGFloat { get }
+}

+ 22 - 0
Libraries external/Sheeeeeeeeet/Views/ActionSheetCustomItemCell.swift

@@ -0,0 +1,22 @@
+//
+//  ActionSheetCustomItemCell.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2018-10-08.
+//  Copyright © 2018 Daniel Saidi. All rights reserved.
+//
+
+/*
+ 
+ This protocol must be implemented by any cell that is to be
+ used together with an `ActionSheetCustomItem`.
+ 
+ */
+
+import UIKit
+
+public protocol ActionSheetCustomItemCell where Self: ActionSheetItemCell {
+    
+    static var nib: UINib { get }
+    static var defaultSize: CGSize { get }
+}

+ 19 - 0
Libraries external/Sheeeeeeeeet/Views/ActionSheetItemCell.swift

@@ -0,0 +1,19 @@
+//
+//  ActionSheetItemCell.swift
+//  Sheeeeeeeeet
+//
+//  Created by Daniel Saidi on 2017-11-24.
+//  Copyright © 2017 Daniel Saidi. All rights reserved.
+//
+
+/*
+ 
+ This is the base class for all different cell types in this
+ library. It makes it possible to set a global appearance on
+ all item cells in an app.
+ 
+ */
+
+import UIKit
+
+open class ActionSheetItemCell: UITableViewCell {}

+ 294 - 0
Nextcloud.xcodeproj/project.pbxproj

@@ -318,6 +318,53 @@
 		F75AE3C71E9D12900088BB09 /* SwiftyAvatar.swift in Sources */ = {isa = PBXBuildFile; fileRef = F75AE3C61E9D12900088BB09 /* SwiftyAvatar.swift */; };
 		F75EDFBD1E8C112F00E6F369 /* libsqlite3.0.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = F75EDFBC1E8C112F00E6F369 /* libsqlite3.0.tbd */; };
 		F75EDFBF1E8C116D00E6F369 /* libstdc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = F75EDFBE1E8C116D00E6F369 /* libstdc++.tbd */; };
+		F7622FAD2175FCC0000383FF /* ActionSheetMargin.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622F712175FCC0000383FF /* ActionSheetMargin.swift */; };
+		F7622FAE2175FCC0000383FF /* ActionSheetItemHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622F722175FCC0000383FF /* ActionSheetItemHandler.swift */; };
+		F7622FAF2175FCC0000383FF /* ActionSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622F732175FCC0000383FF /* ActionSheet.swift */; };
+		F7622FB02175FCC0000383FF /* ActionSheet+Presenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622F742175FCC0000383FF /* ActionSheet+Presenter.swift */; };
+		F7622FB12175FCC0000383FF /* ActionSheetPopoverApperance.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622F762175FCC0000383FF /* ActionSheetPopoverApperance.swift */; };
+		F7622FB22175FCC0000383FF /* ActionSheetItemAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622F772175FCC0000383FF /* ActionSheetItemAppearance.swift */; };
+		F7622FB32175FCC0000383FF /* ActionSheetDangerButtonAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622F792175FCC0000383FF /* ActionSheetDangerButtonAppearance.swift */; };
+		F7622FB42175FCC0000383FF /* ActionSheetOkButtonAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622F7A2175FCC0000383FF /* ActionSheetOkButtonAppearance.swift */; };
+		F7622FB52175FCC0000383FF /* ActionSheetButtonItemAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622F7B2175FCC0000383FF /* ActionSheetButtonItemAppearance.swift */; };
+		F7622FB62175FCC0000383FF /* ActionSheetCancelButtonAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622F7C2175FCC0000383FF /* ActionSheetCancelButtonAppearance.swift */; };
+		F7622FB72175FCC0000383FF /* ActionSheetSectionTitleAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622F7E2175FCC0000383FF /* ActionSheetSectionTitleAppearance.swift */; };
+		F7622FB82175FCC0000383FF /* ActionSheetTitleAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622F7F2175FCC0000383FF /* ActionSheetTitleAppearance.swift */; };
+		F7622FB92175FCC0000383FF /* ActionSheetSectionMarginAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622F802175FCC0000383FF /* ActionSheetSectionMarginAppearance.swift */; };
+		F7622FBA2175FCC0000383FF /* ActionSheetAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622F812175FCC0000383FF /* ActionSheetAppearance.swift */; };
+		F7622FBB2175FCC0000383FF /* ActionSheetSelectItemAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622F832175FCC0000383FF /* ActionSheetSelectItemAppearance.swift */; };
+		F7622FBC2175FCC0000383FF /* ActionSheetMultiSelectToggleItemAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622F842175FCC0000383FF /* ActionSheetMultiSelectToggleItemAppearance.swift */; };
+		F7622FBD2175FCC0000383FF /* ActionSheetSingleSelectItemAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622F852175FCC0000383FF /* ActionSheetSingleSelectItemAppearance.swift */; };
+		F7622FBE2175FCC0000383FF /* ActionSheetCollectionItemAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622F862175FCC0000383FF /* ActionSheetCollectionItemAppearance.swift */; };
+		F7622FBF2175FCC0000383FF /* ActionSheetMultiSelectItemAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622F872175FCC0000383FF /* ActionSheetMultiSelectItemAppearance.swift */; };
+		F7622FC02175FCC0000383FF /* ActionSheetLinkItemAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622F882175FCC0000383FF /* ActionSheetLinkItemAppearance.swift */; };
+		F7622FC12175FCC0000383FF /* ActionSheetCustomItemAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622F892175FCC0000383FF /* ActionSheetCustomItemAppearance.swift */; };
+		F7622FC22175FCC0000383FF /* ActionSheetPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622F8B2175FCC0000383FF /* ActionSheetPresenter.swift */; };
+		F7622FC32175FCC0000383FF /* ActionSheetDefaultPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622F8C2175FCC0000383FF /* ActionSheetDefaultPresenter.swift */; };
+		F7622FC42175FCC0000383FF /* ActionSheetPopoverPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622F8D2175FCC0000383FF /* ActionSheetPopoverPresenter.swift */; };
+		F7622FC52175FCC0000383FF /* NSObject+ClassName.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622F8F2175FCC0000383FF /* NSObject+ClassName.swift */; };
+		F7622FC62175FCC0000383FF /* UIViewController+RootViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622F902175FCC0000383FF /* UIViewController+RootViewController.swift */; };
+		F7622FC72175FCC0000383FF /* UIView+Empty.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622F912175FCC0000383FF /* UIView+Empty.swift */; };
+		F7622FC82175FCC0000383FF /* ActionSheetOkButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622F952175FCC0000383FF /* ActionSheetOkButton.swift */; };
+		F7622FC92175FCC0000383FF /* ActionSheetButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622F962175FCC0000383FF /* ActionSheetButton.swift */; };
+		F7622FCA2175FCC0000383FF /* ActionSheetCancelButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622F972175FCC0000383FF /* ActionSheetCancelButton.swift */; };
+		F7622FCB2175FCC0000383FF /* ActionSheetDangerButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622F982175FCC0000383FF /* ActionSheetDangerButton.swift */; };
+		F7622FCC2175FCC0000383FF /* ActionSheetSectionMargin.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622F9A2175FCC0000383FF /* ActionSheetSectionMargin.swift */; };
+		F7622FCD2175FCC0000383FF /* ActionSheetSectionTitle.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622F9B2175FCC0000383FF /* ActionSheetSectionTitle.swift */; };
+		F7622FCE2175FCC0000383FF /* ActionSheetTitle.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622F9C2175FCC0000383FF /* ActionSheetTitle.swift */; };
+		F7622FCF2175FCC0000383FF /* ActionSheetMultiSelectToggleItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622F9E2175FCC0000383FF /* ActionSheetMultiSelectToggleItem.swift */; };
+		F7622FD02175FCC0000383FF /* ActionSheetCustomItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622F9F2175FCC0000383FF /* ActionSheetCustomItem.swift */; };
+		F7622FD12175FCC0000383FF /* ActionSheetSingleSelectItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622FA02175FCC0000383FF /* ActionSheetSingleSelectItem.swift */; };
+		F7622FD22175FCC0000383FF /* ActionSheetSelectItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622FA12175FCC0000383FF /* ActionSheetSelectItem.swift */; };
+		F7622FD32175FCC0000383FF /* ActionSheetLinkItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622FA22175FCC0000383FF /* ActionSheetLinkItem.swift */; };
+		F7622FD42175FCC0000383FF /* ActionSheetMultiSelectItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622FA32175FCC0000383FF /* ActionSheetMultiSelectItem.swift */; };
+		F7622FD52175FCC0000383FF /* ActionSheetCollectionItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622FA42175FCC0000383FF /* ActionSheetCollectionItem.swift */; };
+		F7622FD62175FCC0000383FF /* ActionSheetItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622FA52175FCC0000383FF /* ActionSheetItem.swift */; };
+		F7622FD72175FCC0000383FF /* ActionSheetItemCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622FA72175FCC0000383FF /* ActionSheetItemCell.swift */; };
+		F7622FD82175FCC0000383FF /* ActionSheetCollectionItemCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622FA82175FCC0000383FF /* ActionSheetCollectionItemCell.swift */; };
+		F7622FD92175FCC0000383FF /* ActionSheetCollectionItemContentCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622FA92175FCC0000383FF /* ActionSheetCollectionItemContentCell.swift */; };
+		F7622FDA2175FCC0000383FF /* ActionSheetCustomItemCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7622FAA2175FCC0000383FF /* ActionSheetCustomItemCell.swift */; };
+		F7622FDB2175FCC0000383FF /* ActionSheetCollectionItemCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = F7622FAB2175FCC0000383FF /* ActionSheetCollectionItemCell.xib */; };
 		F762CAF71EACB66200B38484 /* XLFormBaseCell.m in Sources */ = {isa = PBXBuildFile; fileRef = F762CAA41EACB66200B38484 /* XLFormBaseCell.m */; };
 		F762CAF81EACB66200B38484 /* XLFormButtonCell.m in Sources */ = {isa = PBXBuildFile; fileRef = F762CAA61EACB66200B38484 /* XLFormButtonCell.m */; };
 		F762CAF91EACB66200B38484 /* XLFormCheckCell.m in Sources */ = {isa = PBXBuildFile; fileRef = F762CAA81EACB66200B38484 /* XLFormCheckCell.m */; };
@@ -1111,6 +1158,54 @@
 		F75CDBF51DF063AD00116AD0 /* .gitignore */ = {isa = PBXFileReference; lastKnownFileType = text; name = .gitignore; path = ../.gitignore; sourceTree = "<group>"; };
 		F75EDFBC1E8C112F00E6F369 /* libsqlite3.0.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.0.tbd; path = usr/lib/libsqlite3.0.tbd; sourceTree = SDKROOT; };
 		F75EDFBE1E8C116D00E6F369 /* libstdc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libstdc++.tbd"; path = "usr/lib/libstdc++.tbd"; sourceTree = SDKROOT; };
+		F7622F712175FCC0000383FF /* ActionSheetMargin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetMargin.swift; sourceTree = "<group>"; };
+		F7622F722175FCC0000383FF /* ActionSheetItemHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetItemHandler.swift; sourceTree = "<group>"; };
+		F7622F732175FCC0000383FF /* ActionSheet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheet.swift; sourceTree = "<group>"; };
+		F7622F742175FCC0000383FF /* ActionSheet+Presenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ActionSheet+Presenter.swift"; sourceTree = "<group>"; };
+		F7622F762175FCC0000383FF /* ActionSheetPopoverApperance.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetPopoverApperance.swift; sourceTree = "<group>"; };
+		F7622F772175FCC0000383FF /* ActionSheetItemAppearance.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetItemAppearance.swift; sourceTree = "<group>"; };
+		F7622F792175FCC0000383FF /* ActionSheetDangerButtonAppearance.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetDangerButtonAppearance.swift; sourceTree = "<group>"; };
+		F7622F7A2175FCC0000383FF /* ActionSheetOkButtonAppearance.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetOkButtonAppearance.swift; sourceTree = "<group>"; };
+		F7622F7B2175FCC0000383FF /* ActionSheetButtonItemAppearance.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetButtonItemAppearance.swift; sourceTree = "<group>"; };
+		F7622F7C2175FCC0000383FF /* ActionSheetCancelButtonAppearance.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetCancelButtonAppearance.swift; sourceTree = "<group>"; };
+		F7622F7E2175FCC0000383FF /* ActionSheetSectionTitleAppearance.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetSectionTitleAppearance.swift; sourceTree = "<group>"; };
+		F7622F7F2175FCC0000383FF /* ActionSheetTitleAppearance.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetTitleAppearance.swift; sourceTree = "<group>"; };
+		F7622F802175FCC0000383FF /* ActionSheetSectionMarginAppearance.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetSectionMarginAppearance.swift; sourceTree = "<group>"; };
+		F7622F812175FCC0000383FF /* ActionSheetAppearance.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetAppearance.swift; sourceTree = "<group>"; };
+		F7622F832175FCC0000383FF /* ActionSheetSelectItemAppearance.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetSelectItemAppearance.swift; sourceTree = "<group>"; };
+		F7622F842175FCC0000383FF /* ActionSheetMultiSelectToggleItemAppearance.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetMultiSelectToggleItemAppearance.swift; sourceTree = "<group>"; };
+		F7622F852175FCC0000383FF /* ActionSheetSingleSelectItemAppearance.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetSingleSelectItemAppearance.swift; sourceTree = "<group>"; };
+		F7622F862175FCC0000383FF /* ActionSheetCollectionItemAppearance.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetCollectionItemAppearance.swift; sourceTree = "<group>"; };
+		F7622F872175FCC0000383FF /* ActionSheetMultiSelectItemAppearance.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetMultiSelectItemAppearance.swift; sourceTree = "<group>"; };
+		F7622F882175FCC0000383FF /* ActionSheetLinkItemAppearance.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetLinkItemAppearance.swift; sourceTree = "<group>"; };
+		F7622F892175FCC0000383FF /* ActionSheetCustomItemAppearance.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetCustomItemAppearance.swift; sourceTree = "<group>"; };
+		F7622F8B2175FCC0000383FF /* ActionSheetPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetPresenter.swift; sourceTree = "<group>"; };
+		F7622F8C2175FCC0000383FF /* ActionSheetDefaultPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetDefaultPresenter.swift; sourceTree = "<group>"; };
+		F7622F8D2175FCC0000383FF /* ActionSheetPopoverPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetPopoverPresenter.swift; sourceTree = "<group>"; };
+		F7622F8F2175FCC0000383FF /* NSObject+ClassName.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSObject+ClassName.swift"; sourceTree = "<group>"; };
+		F7622F902175FCC0000383FF /* UIViewController+RootViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+RootViewController.swift"; sourceTree = "<group>"; };
+		F7622F912175FCC0000383FF /* UIView+Empty.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+Empty.swift"; sourceTree = "<group>"; };
+		F7622F922175FCC0000383FF /* Sheeeeeeeeet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Sheeeeeeeeet.h; sourceTree = "<group>"; };
+		F7622F952175FCC0000383FF /* ActionSheetOkButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetOkButton.swift; sourceTree = "<group>"; };
+		F7622F962175FCC0000383FF /* ActionSheetButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetButton.swift; sourceTree = "<group>"; };
+		F7622F972175FCC0000383FF /* ActionSheetCancelButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetCancelButton.swift; sourceTree = "<group>"; };
+		F7622F982175FCC0000383FF /* ActionSheetDangerButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetDangerButton.swift; sourceTree = "<group>"; };
+		F7622F9A2175FCC0000383FF /* ActionSheetSectionMargin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetSectionMargin.swift; sourceTree = "<group>"; };
+		F7622F9B2175FCC0000383FF /* ActionSheetSectionTitle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetSectionTitle.swift; sourceTree = "<group>"; };
+		F7622F9C2175FCC0000383FF /* ActionSheetTitle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetTitle.swift; sourceTree = "<group>"; };
+		F7622F9E2175FCC0000383FF /* ActionSheetMultiSelectToggleItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetMultiSelectToggleItem.swift; sourceTree = "<group>"; };
+		F7622F9F2175FCC0000383FF /* ActionSheetCustomItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetCustomItem.swift; sourceTree = "<group>"; };
+		F7622FA02175FCC0000383FF /* ActionSheetSingleSelectItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetSingleSelectItem.swift; sourceTree = "<group>"; };
+		F7622FA12175FCC0000383FF /* ActionSheetSelectItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetSelectItem.swift; sourceTree = "<group>"; };
+		F7622FA22175FCC0000383FF /* ActionSheetLinkItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetLinkItem.swift; sourceTree = "<group>"; };
+		F7622FA32175FCC0000383FF /* ActionSheetMultiSelectItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetMultiSelectItem.swift; sourceTree = "<group>"; };
+		F7622FA42175FCC0000383FF /* ActionSheetCollectionItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetCollectionItem.swift; sourceTree = "<group>"; };
+		F7622FA52175FCC0000383FF /* ActionSheetItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetItem.swift; sourceTree = "<group>"; };
+		F7622FA72175FCC0000383FF /* ActionSheetItemCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetItemCell.swift; sourceTree = "<group>"; };
+		F7622FA82175FCC0000383FF /* ActionSheetCollectionItemCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetCollectionItemCell.swift; sourceTree = "<group>"; };
+		F7622FA92175FCC0000383FF /* ActionSheetCollectionItemContentCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetCollectionItemContentCell.swift; sourceTree = "<group>"; };
+		F7622FAA2175FCC0000383FF /* ActionSheetCustomItemCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionSheetCustomItemCell.swift; sourceTree = "<group>"; };
+		F7622FAB2175FCC0000383FF /* ActionSheetCollectionItemCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ActionSheetCollectionItemCell.xib; sourceTree = "<group>"; };
 		F762CAA31EACB66200B38484 /* XLFormBaseCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XLFormBaseCell.h; sourceTree = "<group>"; };
 		F762CAA41EACB66200B38484 /* XLFormBaseCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XLFormBaseCell.m; sourceTree = "<group>"; };
 		F762CAA51EACB66200B38484 /* XLFormButtonCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XLFormButtonCell.h; sourceTree = "<group>"; };
@@ -1772,6 +1867,7 @@
 				F70F05241C889184008DAB36 /* Reachability */,
 				F7DFE24E1EBDC3A400CF5202 /* Realm */,
 				F7A55417204EF8AF008468EC /* TOScrollBar */,
+				F7622F6F2175FCC0000383FF /* Sheeeeeeeeet */,
 				F75AE3C51E9D12900088BB09 /* SwiftyAvatar */,
 				F73CCE271DC13798007E38D8 /* UICKeyChainStore */,
 				F70F05561C889184008DAB36 /* UIImage+animatedGIF */,
@@ -2358,6 +2454,157 @@
 			path = SwiftyAvatar;
 			sourceTree = "<group>";
 		};
+		F7622F6F2175FCC0000383FF /* Sheeeeeeeeet */ = {
+			isa = PBXGroup;
+			children = (
+				F7622F702175FCC0000383FF /* ActionSheet */,
+				F7622F752175FCC0000383FF /* Appearance */,
+				F7622F8A2175FCC0000383FF /* Presenters */,
+				F7622F8E2175FCC0000383FF /* Extensions */,
+				F7622F922175FCC0000383FF /* Sheeeeeeeeet.h */,
+				F7622F932175FCC0000383FF /* Items */,
+				F7622FA62175FCC0000383FF /* Views */,
+			);
+			path = Sheeeeeeeeet;
+			sourceTree = "<group>";
+		};
+		F7622F702175FCC0000383FF /* ActionSheet */ = {
+			isa = PBXGroup;
+			children = (
+				F7622F712175FCC0000383FF /* ActionSheetMargin.swift */,
+				F7622F722175FCC0000383FF /* ActionSheetItemHandler.swift */,
+				F7622F732175FCC0000383FF /* ActionSheet.swift */,
+				F7622F742175FCC0000383FF /* ActionSheet+Presenter.swift */,
+			);
+			path = ActionSheet;
+			sourceTree = "<group>";
+		};
+		F7622F752175FCC0000383FF /* Appearance */ = {
+			isa = PBXGroup;
+			children = (
+				F7622F762175FCC0000383FF /* ActionSheetPopoverApperance.swift */,
+				F7622F772175FCC0000383FF /* ActionSheetItemAppearance.swift */,
+				F7622F782175FCC0000383FF /* Buttons */,
+				F7622F7D2175FCC0000383FF /* Titles */,
+				F7622F812175FCC0000383FF /* ActionSheetAppearance.swift */,
+				F7622F822175FCC0000383FF /* Items */,
+			);
+			path = Appearance;
+			sourceTree = "<group>";
+		};
+		F7622F782175FCC0000383FF /* Buttons */ = {
+			isa = PBXGroup;
+			children = (
+				F7622F792175FCC0000383FF /* ActionSheetDangerButtonAppearance.swift */,
+				F7622F7A2175FCC0000383FF /* ActionSheetOkButtonAppearance.swift */,
+				F7622F7B2175FCC0000383FF /* ActionSheetButtonItemAppearance.swift */,
+				F7622F7C2175FCC0000383FF /* ActionSheetCancelButtonAppearance.swift */,
+			);
+			path = Buttons;
+			sourceTree = "<group>";
+		};
+		F7622F7D2175FCC0000383FF /* Titles */ = {
+			isa = PBXGroup;
+			children = (
+				F7622F7E2175FCC0000383FF /* ActionSheetSectionTitleAppearance.swift */,
+				F7622F7F2175FCC0000383FF /* ActionSheetTitleAppearance.swift */,
+				F7622F802175FCC0000383FF /* ActionSheetSectionMarginAppearance.swift */,
+			);
+			path = Titles;
+			sourceTree = "<group>";
+		};
+		F7622F822175FCC0000383FF /* Items */ = {
+			isa = PBXGroup;
+			children = (
+				F7622F832175FCC0000383FF /* ActionSheetSelectItemAppearance.swift */,
+				F7622F842175FCC0000383FF /* ActionSheetMultiSelectToggleItemAppearance.swift */,
+				F7622F852175FCC0000383FF /* ActionSheetSingleSelectItemAppearance.swift */,
+				F7622F862175FCC0000383FF /* ActionSheetCollectionItemAppearance.swift */,
+				F7622F872175FCC0000383FF /* ActionSheetMultiSelectItemAppearance.swift */,
+				F7622F882175FCC0000383FF /* ActionSheetLinkItemAppearance.swift */,
+				F7622F892175FCC0000383FF /* ActionSheetCustomItemAppearance.swift */,
+			);
+			path = Items;
+			sourceTree = "<group>";
+		};
+		F7622F8A2175FCC0000383FF /* Presenters */ = {
+			isa = PBXGroup;
+			children = (
+				F7622F8B2175FCC0000383FF /* ActionSheetPresenter.swift */,
+				F7622F8C2175FCC0000383FF /* ActionSheetDefaultPresenter.swift */,
+				F7622F8D2175FCC0000383FF /* ActionSheetPopoverPresenter.swift */,
+			);
+			path = Presenters;
+			sourceTree = "<group>";
+		};
+		F7622F8E2175FCC0000383FF /* Extensions */ = {
+			isa = PBXGroup;
+			children = (
+				F7622F8F2175FCC0000383FF /* NSObject+ClassName.swift */,
+				F7622F902175FCC0000383FF /* UIViewController+RootViewController.swift */,
+				F7622F912175FCC0000383FF /* UIView+Empty.swift */,
+			);
+			path = Extensions;
+			sourceTree = "<group>";
+		};
+		F7622F932175FCC0000383FF /* Items */ = {
+			isa = PBXGroup;
+			children = (
+				F7622F942175FCC0000383FF /* Buttons */,
+				F7622F992175FCC0000383FF /* Titles */,
+				F7622F9D2175FCC0000383FF /* Items */,
+				F7622FA52175FCC0000383FF /* ActionSheetItem.swift */,
+			);
+			path = Items;
+			sourceTree = "<group>";
+		};
+		F7622F942175FCC0000383FF /* Buttons */ = {
+			isa = PBXGroup;
+			children = (
+				F7622F952175FCC0000383FF /* ActionSheetOkButton.swift */,
+				F7622F962175FCC0000383FF /* ActionSheetButton.swift */,
+				F7622F972175FCC0000383FF /* ActionSheetCancelButton.swift */,
+				F7622F982175FCC0000383FF /* ActionSheetDangerButton.swift */,
+			);
+			path = Buttons;
+			sourceTree = "<group>";
+		};
+		F7622F992175FCC0000383FF /* Titles */ = {
+			isa = PBXGroup;
+			children = (
+				F7622F9A2175FCC0000383FF /* ActionSheetSectionMargin.swift */,
+				F7622F9B2175FCC0000383FF /* ActionSheetSectionTitle.swift */,
+				F7622F9C2175FCC0000383FF /* ActionSheetTitle.swift */,
+			);
+			path = Titles;
+			sourceTree = "<group>";
+		};
+		F7622F9D2175FCC0000383FF /* Items */ = {
+			isa = PBXGroup;
+			children = (
+				F7622F9E2175FCC0000383FF /* ActionSheetMultiSelectToggleItem.swift */,
+				F7622F9F2175FCC0000383FF /* ActionSheetCustomItem.swift */,
+				F7622FA02175FCC0000383FF /* ActionSheetSingleSelectItem.swift */,
+				F7622FA12175FCC0000383FF /* ActionSheetSelectItem.swift */,
+				F7622FA22175FCC0000383FF /* ActionSheetLinkItem.swift */,
+				F7622FA32175FCC0000383FF /* ActionSheetMultiSelectItem.swift */,
+				F7622FA42175FCC0000383FF /* ActionSheetCollectionItem.swift */,
+			);
+			path = Items;
+			sourceTree = "<group>";
+		};
+		F7622FA62175FCC0000383FF /* Views */ = {
+			isa = PBXGroup;
+			children = (
+				F7622FA72175FCC0000383FF /* ActionSheetItemCell.swift */,
+				F7622FA82175FCC0000383FF /* ActionSheetCollectionItemCell.swift */,
+				F7622FA92175FCC0000383FF /* ActionSheetCollectionItemContentCell.swift */,
+				F7622FAA2175FCC0000383FF /* ActionSheetCustomItemCell.swift */,
+				F7622FAB2175FCC0000383FF /* ActionSheetCollectionItemCell.xib */,
+			);
+			path = Views;
+			sourceTree = "<group>";
+		};
 		F762CA9F1EACB66200B38484 /* XLForm */ = {
 			isa = PBXGroup;
 			children = (
@@ -3509,6 +3756,7 @@
 				F7F54CF91E5B14C700E19C62 /* PlayButtonOverlayLargeTap@3x.png in Resources */,
 				F7D4233D1F0596AC009C9782 /* Reader-Button-N@3x.png in Resources */,
 				F73B4EF21F470D9100BBEE4B /* EUCTWFreq.tab in Resources */,
+				F7622FDB2175FCC0000383FF /* ActionSheetCollectionItemCell.xib in Resources */,
 				F700222C1EC479840080073F /* Custom.xcassets in Resources */,
 				F758B45A212C564000515F55 /* Scan.storyboard in Resources */,
 				F77B0EFE1D118A16002130FE /* CCUploadFromOtherUpp.storyboard in Resources */,
@@ -3808,6 +4056,7 @@
 			buildActionMask = 2147483647;
 			files = (
 				F70022D71EC4C9100080073F /* NSDate+RFC1123.m in Sources */,
+				F7622FC52175FCC0000383FF /* NSObject+ClassName.swift in Sources */,
 				F70022A41EC4C9100080073F /* AFNetworkReachabilityManager.m in Sources */,
 				F762CAFD1EACB66200B38484 /* XLFormInlineSelectorCell.m in Sources */,
 				F77B0DF21D118A16002130FE /* CCUploadFromOtherUpp.m in Sources */,
@@ -3825,11 +4074,13 @@
 				F73B4EEF1F470D9100BBEE4B /* CharDistribution.cpp in Sources */,
 				F7B0C0CD1EE7E7750033AC24 /* CCSynchronize.m in Sources */,
 				F77B0DFF1D118A16002130FE /* OCNetworking.m in Sources */,
+				F7622FC82175FCC0000383FF /* ActionSheetOkButton.swift in Sources */,
 				F758B440212C516300515F55 /* CaptureSessionManager.swift in Sources */,
 				F73B4F081F470D9100BBEE4B /* nsEUCJPProber.cpp in Sources */,
 				F712AC992175E56F0061158E /* CTAssetsNavigationController.m in Sources */,
 				F758B43F212C516300515F55 /* RectangleFeaturesFunnel.swift in Sources */,
 				F70022DA1EC4C9100080073F /* OCHTTPRequestOperation.m in Sources */,
+				F7622FCD2175FCC0000383FF /* ActionSheetSectionTitle.swift in Sources */,
 				F790110E21415BF600D7B136 /* NCViewerRichdocument.swift in Sources */,
 				F70022A11EC4C9100080073F /* AFHTTPSessionManager.m in Sources */,
 				F762CB041EACB66200B38484 /* XLFormSwitchCell.m in Sources */,
@@ -3838,11 +4089,15 @@
 				F712ACA52175E56F0061158E /* CTAssetThumbnailView.m in Sources */,
 				F77B0E031D118A16002130FE /* CCShareInfoCMOC.m in Sources */,
 				F77B0E041D118A16002130FE /* UIImage+animatedGIF.m in Sources */,
+				F7622FCE2175FCC0000383FF /* ActionSheetTitle.swift in Sources */,
+				F7622FBD2175FCC0000383FF /* ActionSheetSingleSelectItemAppearance.swift in Sources */,
 				F712ACB22175E56F0061158E /* CTAssetsGridViewController.m in Sources */,
 				F7D423881F0596C6009C9782 /* ReaderThumbView.m in Sources */,
+				F7622FC32175FCC0000383FF /* ActionSheetDefaultPresenter.swift in Sources */,
 				F73CCE301DC13798007E38D8 /* UICKeyChainStore.m in Sources */,
 				F758B44B212C516300515F55 /* CIRectangleFeature+Utils.swift in Sources */,
 				F73B4EFE1F470D9100BBEE4B /* LangHungarianModel.cpp in Sources */,
+				F7622FC12175FCC0000383FF /* ActionSheetCustomItemAppearance.swift in Sources */,
 				F758B442212C516300515F55 /* CloseButton.swift in Sources */,
 				F7D4238A1F0596C6009C9782 /* ThumbsMainToolbar.m in Sources */,
 				F70022EC1EC4C9100080073F /* OCXMLSharedParser.m in Sources */,
@@ -3854,12 +4109,14 @@
 				F712AC962175E56F0061158E /* CTAssetThumbnailStacks.m in Sources */,
 				F712ACB02175E56F0061158E /* PHImageManager+CTAssetsPickerController.m in Sources */,
 				F7B1FBC71E72E3D1001781FE /* SwiftWebVC.swift in Sources */,
+				F7622FB62175FCC0000383FF /* ActionSheetCancelButtonAppearance.swift in Sources */,
 				F7DC5FEC1F011EB700A903C7 /* MGSwipeButton.m in Sources */,
 				F7D423801F0596C6009C9782 /* ReaderMainPagebar.m in Sources */,
 				F712ACAA2175E56F0061158E /* NSNumberFormatter+CTAssetsPickerController.m in Sources */,
 				F762CB061EACB66200B38484 /* XLFormTextViewCell.m in Sources */,
 				F758B3E7212C4A6C00515F55 /* PDFGenerateError.swift in Sources */,
 				F762CB881EACB81000B38484 /* REMenuContainerView.m in Sources */,
+				F7622FBC2175FCC0000383FF /* ActionSheetMultiSelectToggleItemAppearance.swift in Sources */,
 				F7D4237F1F0596C6009C9782 /* ReaderDocumentOutline.m in Sources */,
 				F73F537F1E929C8500F8678D /* CCMore.swift in Sources */,
 				F73B4EF71F470D9100BBEE4B /* LangBulgarianModel.cpp in Sources */,
@@ -3869,6 +4126,7 @@
 				F758B3E4212C4A6C00515F55 /* PDFGenerator.swift in Sources */,
 				F712AC982175E56F0061158E /* CTAssetsPageViewController.m in Sources */,
 				F7B1FBC61E72E3D1001781FE /* SwiftModalWebVC.swift in Sources */,
+				F7622FD02175FCC0000383FF /* ActionSheetCustomItem.swift in Sources */,
 				F7A5541F204EF8AF008468EC /* TOScrollBar.m in Sources */,
 				F7A321651E9E37960069AD1B /* CCActivity.m in Sources */,
 				F7FB1D3E215E191D00D669EA /* NCViewerDocumentWeb.swift in Sources */,
@@ -3876,6 +4134,7 @@
 				F762CB0C1EACB66200B38484 /* XLFormSectionDescriptor.m in Sources */,
 				F77B0E131D118A16002130FE /* AppDelegate.m in Sources */,
 				F762CB861EACB81000B38484 /* RECommonFunctions.m in Sources */,
+				F7622FC62175FCC0000383FF /* UIViewController+RootViewController.swift in Sources */,
 				F758B443212C516300515F55 /* ScannerViewController.swift in Sources */,
 				F750374F1DBFA91A008FB480 /* NSArray+PureLayout.m in Sources */,
 				F77B0E141D118A16002130FE /* CCError.m in Sources */,
@@ -3888,6 +4147,8 @@
 				F758B460212C56A400515F55 /* ScanCollectionView.swift in Sources */,
 				F762CB021EACB66200B38484 /* XLFormSliderCell.m in Sources */,
 				F77B0E1B1D118A16002130FE /* CCGraphics.m in Sources */,
+				F7622FB92175FCC0000383FF /* ActionSheetSectionMarginAppearance.swift in Sources */,
+				F7622FC72175FCC0000383FF /* UIView+Empty.swift in Sources */,
 				F70022CB1EC4C9100080073F /* OCSharedDto.m in Sources */,
 				F7CA1ED320E7E3FE002CC65E /* PKStopDownloadButton.m in Sources */,
 				F712ACA12175E56F0061158E /* CTAssetsViewControllerTransition.m in Sources */,
@@ -3909,15 +4170,19 @@
 				F77B0E221D118A16002130FE /* CCManageLocation.m in Sources */,
 				F70022C51EC4C9100080073F /* OCNotificationsAction.m in Sources */,
 				F7D6650720FF341600BFBA9E /* NCMainCommon.swift in Sources */,
+				F7622FAF2175FCC0000383FF /* ActionSheet.swift in Sources */,
 				F77B0E231D118A16002130FE /* CCSharePermissionOC.m in Sources */,
+				F7622FD12175FCC0000383FF /* ActionSheetSingleSelectItem.swift in Sources */,
 				F762CAF81EACB66200B38484 /* XLFormButtonCell.m in Sources */,
 				F7CA1ED120E7E3FE002CC65E /* PKCircleProgressView.m in Sources */,
 				F712ACA82175E56F0061158E /* PHAssetCollection+CTAssetsPickerController.m in Sources */,
 				F75AE3C71E9D12900088BB09 /* SwiftyAvatar.swift in Sources */,
+				F7622FB02175FCC0000383FF /* ActionSheet+Presenter.swift in Sources */,
 				F762CAFC1EACB66200B38484 /* XLFormImageCell.m in Sources */,
 				F72D1007210B6882009C96B7 /* NCPushNotificationEncryption.m in Sources */,
 				F70022D11EC4C9100080073F /* OCUserProfile.m in Sources */,
 				F73B4EF61F470D9100BBEE4B /* LangArabicModel.cpp in Sources */,
+				F7622FCC2175FCC0000383FF /* ActionSheetSectionMargin.swift in Sources */,
 				F7CA1ED420E7E3FE002CC65E /* PKPendingView.m in Sources */,
 				F73B4F0B1F470D9100BBEE4B /* nsGB2312Prober.cpp in Sources */,
 				F762CAFE1EACB66200B38484 /* XLFormLeftRightSelectorCell.m in Sources */,
@@ -3932,15 +4197,20 @@
 				F78964AE1EBB576C00403E13 /* JDStatusBarStyle.m in Sources */,
 				F7EC9CBC21185F2000F1C5CE /* CCMedia.m in Sources */,
 				F7D423831F0596C6009C9782 /* ReaderThumbFetch.m in Sources */,
+				F7622FD92175FCC0000383FF /* ActionSheetCollectionItemContentCell.swift in Sources */,
 				F73B4F171F470D9100BBEE4B /* uchardet.cpp in Sources */,
 				F7D4237A1F0596C6009C9782 /* ReaderConstants.m in Sources */,
 				F73B4F121F470D9100BBEE4B /* nsSJISProber.cpp in Sources */,
 				F762CAFF1EACB66200B38484 /* XLFormPickerCell.m in Sources */,
+				F7622FBA2175FCC0000383FF /* ActionSheetAppearance.swift in Sources */,
 				F7A321AD1E9E6AD50069AD1B /* CCAdvanced.m in Sources */,
 				F710E8101EF95C9C00DC2427 /* CCIntro.m in Sources */,
+				F7622FB72175FCC0000383FF /* ActionSheetSectionTitleAppearance.swift in Sources */,
+				F7622FB42175FCC0000383FF /* ActionSheetOkButtonAppearance.swift in Sources */,
 				F77B0E411D118A16002130FE /* CCSplit.m in Sources */,
 				F73CC0781E813DFF006E3047 /* BKShiftingView.m in Sources */,
 				F7A3218C1E9E42B30069AD1B /* CCMenuAccount.m in Sources */,
+				F7622FD52175FCC0000383FF /* ActionSheetCollectionItem.swift in Sources */,
 				F712AC9F2175E56F0061158E /* CTAssetsPickerAccessDeniedView.m in Sources */,
 				F77B0E4C1D118A16002130FE /* CCDetail.m in Sources */,
 				F762CB191EACB66200B38484 /* XLFormValidator.m in Sources */,
@@ -3950,16 +4220,20 @@
 				F712ACAC2175E56F0061158E /* UICollectionView+CTAssetsPickerController.m in Sources */,
 				F7FCFFE01D707B83000E6E29 /* CCPeekPop.m in Sources */,
 				F7BAADC81ED5A87C00B7EAD4 /* NCDatabase.swift in Sources */,
+				F7622FD32175FCC0000383FF /* ActionSheetLinkItem.swift in Sources */,
 				F712AC922175E56F0061158E /* CTAssetItemViewController.m in Sources */,
 				F77B0E541D118A16002130FE /* CCMove.m in Sources */,
+				F7622FC42175FCC0000383FF /* ActionSheetPopoverPresenter.swift in Sources */,
 				F712ACA72175E56F0061158E /* CTAssetCollectionViewCell.m in Sources */,
 				F7A5541E204EF8AF008468EC /* TOScrollBarGestureRecognizer.m in Sources */,
+				F7622FCB2175FCC0000383FF /* ActionSheetDangerButton.swift in Sources */,
 				F758B452212C516300515F55 /* Quadrilateral.swift in Sources */,
 				F712AC952175E56F0061158E /* CTAssetScrollView.m in Sources */,
 				F70022E61EC4C9100080073F /* OCXMLServerErrorsParser.m in Sources */,
 				F758B3E1212C4A6C00515F55 /* PDFPageRenderable.swift in Sources */,
 				F762CB171EACB66200B38484 /* XLFormRegexValidator.m in Sources */,
 				F758B44F212C516300515F55 /* Error.swift in Sources */,
+				F7622FBE2175FCC0000383FF /* ActionSheetCollectionItemAppearance.swift in Sources */,
 				F73CC0691E813DFF006E3047 /* BKPasscodeDummyViewController.m in Sources */,
 				F762CB1A1EACB66200B38484 /* XLForm.m in Sources */,
 				F73B4EFC1F470D9100BBEE4B /* LangGreekModel.cpp in Sources */,
@@ -3975,9 +4249,11 @@
 				F7BE6E2F1D2D5C3B00106933 /* CCQuickActions.m in Sources */,
 				F7ED7EDE216B85DA007AB4D9 /* NCTrashListCell.swift in Sources */,
 				F762CB101EACB66200B38484 /* NSPredicate+XLFormAdditions.m in Sources */,
+				F7622FCF2175FCC0000383FF /* ActionSheetMultiSelectToggleItem.swift in Sources */,
 				F7D4237E1F0596C6009C9782 /* ReaderDocument.m in Sources */,
 				F7659A291DC0B726004860C4 /* EAIntroView.m in Sources */,
 				F7D4237C1F0596C6009C9782 /* ReaderContentTile.m in Sources */,
+				F7622FD42175FCC0000383FF /* ActionSheetMultiSelectItem.swift in Sources */,
 				F73CC07E1E813DFF006E3047 /* BKTouchIDSwitchView.m in Sources */,
 				F77B0E5F1D118A16002130FE /* CCSettings.m in Sources */,
 				F78F74362163781100C2ADAD /* NCTrash.swift in Sources */,
@@ -3999,6 +4275,7 @@
 				F73CC0751E813DFF006E3047 /* BKPasscodeViewController.m in Sources */,
 				F750374D1DBFA91A008FB480 /* ALView+PureLayout.m in Sources */,
 				F7659A2E1DC0B72F004860C4 /* EARestrictedScrollView.m in Sources */,
+				F7622FCA2175FCC0000383FF /* ActionSheetCancelButton.swift in Sources */,
 				F712AC972175E56F0061158E /* CTAssetsPageView.m in Sources */,
 				F7D423861F0596C6009C9782 /* ReaderThumbRequest.m in Sources */,
 				F73B4EF51F470D9100BBEE4B /* JpCntx.cpp in Sources */,
@@ -4009,23 +4286,28 @@
 				F7BF1B431D51E893000854F6 /* CCLogin.m in Sources */,
 				F70022FB1EC4C9100080073F /* NSString+Encode.m in Sources */,
 				F75037511DBFA91A008FB480 /* NSLayoutConstraint+PureLayout.m in Sources */,
+				F7622FD62175FCC0000383FF /* ActionSheetItem.swift in Sources */,
 				F762CAFA1EACB66200B38484 /* XLFormDateCell.m in Sources */,
 				F70022B91EC4C9100080073F /* OCCommunication.m in Sources */,
 				F712ACAD2175E56F0061158E /* PHAsset+CTAssetsPickerController.m in Sources */,
 				F762CB181EACB66200B38484 /* XLFormValidationStatus.m in Sources */,
+				F7622FC92175FCC0000383FF /* ActionSheetButton.swift in Sources */,
 				F73B4EF91F470D9100BBEE4B /* LangEsperantoModel.cpp in Sources */,
 				F77B0E8F1D118A16002130FE /* CCSection.m in Sources */,
 				F7CA1ED720E7E3FE002CC65E /* PKDownloadButton.m in Sources */,
 				F712ACA92175E56F0061158E /* UIImage+CTAssetsPickerController.m in Sources */,
 				F72AAECB1E5C60C700BB17E1 /* AHKActionSheetViewController.m in Sources */,
+				F7622FBF2175FCC0000383FF /* ActionSheetMultiSelectItemAppearance.swift in Sources */,
 				F77B0E921D118A16002130FE /* CCCellMainTransfer.m in Sources */,
 				F758B44A212C516300515F55 /* UIImage+Utils.swift in Sources */,
 				F7659A391DC0B737004860C4 /* iRate.m in Sources */,
 				F7B1FBC81E72E3D1001781FE /* SwiftWebVCActivity.swift in Sources */,
 				F77B0E981D118A16002130FE /* CCManageAccount.m in Sources */,
+				F7622FD72175FCC0000383FF /* ActionSheetItemCell.swift in Sources */,
 				F762CB011EACB66200B38484 /* XLFormSelectorCell.m in Sources */,
 				F755BD9B20594AC7008C5FBB /* NCService.swift in Sources */,
 				F70022AD1EC4C9100080073F /* AFURLResponseSerialization.m in Sources */,
+				F7622FAD2175FCC0000383FF /* ActionSheetMargin.swift in Sources */,
 				F77B0E9B1D118A16002130FE /* CCBKPasscode.m in Sources */,
 				F7659A271DC0B726004860C4 /* EAIntroPage.m in Sources */,
 				F7169A1D1EE590930086BD69 /* NCSharesCell.m in Sources */,
@@ -4056,18 +4338,22 @@
 				F762CB0A1EACB66200B38484 /* XLFormDescriptor.m in Sources */,
 				F7D4238C1F0596C6009C9782 /* UIXToolbarView.m in Sources */,
 				F726EEEC1FED1C820030B9C8 /* NCEndToEndInitialize.swift in Sources */,
+				F7622FBB2175FCC0000383FF /* ActionSheetSelectItemAppearance.swift in Sources */,
+				F7622FB12175FCC0000383FF /* ActionSheetPopoverApperance.swift in Sources */,
 				F712ACA22175E56F0061158E /* CTAssetsGridSelectedView.m in Sources */,
 				F70CAE3A1F8CF31A008125FD /* NCEndToEndEncryption.m in Sources */,
 				F73B4F0C1F470D9100BBEE4B /* nsHebrewProber.cpp in Sources */,
 				F762CAFB1EACB66200B38484 /* XLFormDatePickerCell.m in Sources */,
 				F762CB0F1EACB66200B38484 /* NSObject+XLFormAdditions.m in Sources */,
 				F7B2DEF01F976854007CF4D2 /* NYMnemonic.m in Sources */,
+				F7622FD82175FCC0000383FF /* ActionSheetCollectionItemCell.swift in Sources */,
 				F762CB891EACB81000B38484 /* REMenuItem.m in Sources */,
 				F7D423791F0596C6009C9782 /* CGPDFDocument.m in Sources */,
 				F73B4EFF1F470D9100BBEE4B /* LangRussianModel.cpp in Sources */,
 				F7BAADCB1ED5A87C00B7EAD4 /* NCManageDatabase.swift in Sources */,
 				F7A321551E9E2A070069AD1B /* CCFavorites.m in Sources */,
 				F73B4F031F470D9100BBEE4B /* LangVietnameseModel.cpp in Sources */,
+				F7622FC22175FCC0000383FF /* ActionSheetPresenter.swift in Sources */,
 				F73B4F021F470D9100BBEE4B /* LangTurkishModel.cpp in Sources */,
 				F712ACB12175E56F0061158E /* CTAssetSelectionButton.m in Sources */,
 				F7F54D0B1E5B14C800E19C62 /* MWTapDetectingImageView.m in Sources */,
@@ -4075,8 +4361,11 @@
 				F712AC9A2175E56F0061158E /* CTAssetsGridViewLayout.m in Sources */,
 				F758B3E5212C4A6C00515F55 /* FilePathConvertible.swift in Sources */,
 				F7D423821F0596C6009C9782 /* ReaderThumbCache.m in Sources */,
+				F7622FB22175FCC0000383FF /* ActionSheetItemAppearance.swift in Sources */,
 				F70022A71EC4C9100080073F /* AFSecurityPolicy.m in Sources */,
+				F7622FC02175FCC0000383FF /* ActionSheetLinkItemAppearance.swift in Sources */,
 				F78964AF1EBB576C00403E13 /* JDStatusBarView.m in Sources */,
+				F7622FB82175FCC0000383FF /* ActionSheetTitleAppearance.swift in Sources */,
 				F7CA1ED220E7E3FE002CC65E /* PKCircleView.m in Sources */,
 				F7F54D0D1E5B14C800E19C62 /* MWZoomingScrollView.m in Sources */,
 				F762CB0B1EACB66200B38484 /* XLFormRowDescriptor.m in Sources */,
@@ -4084,9 +4373,12 @@
 				F77B0EC61D118A16002130FE /* CCCellMain.m in Sources */,
 				F758B3E6212C4A6C00515F55 /* PDFPage.swift in Sources */,
 				F7DC5FED1F011EB700A903C7 /* MGSwipeTableCell.m in Sources */,
+				F7622FB32175FCC0000383FF /* ActionSheetDangerButtonAppearance.swift in Sources */,
 				F7D4238B1F0596C6009C9782 /* ThumbsViewController.m in Sources */,
+				F7622FB52175FCC0000383FF /* ActionSheetButtonItemAppearance.swift in Sources */,
 				F70022B61EC4C9100080073F /* OCCapabilities.m in Sources */,
 				F7D423811F0596C6009C9782 /* ReaderMainToolbar.m in Sources */,
+				F7622FDA2175FCC0000383FF /* ActionSheetCustomItemCell.swift in Sources */,
 				F762CB131EACB66200B38484 /* XLFormRightDetailCell.m in Sources */,
 				F7CA1ED820E7E3FE002CC65E /* PKBorderedButton.m in Sources */,
 				F758B441212C516300515F55 /* ShutterButton.swift in Sources */,
@@ -4105,6 +4397,7 @@
 				F758B454212C516300515F55 /* Transformable.swift in Sources */,
 				F712AC912175E56F0061158E /* CTAssetsGridViewCell.m in Sources */,
 				F7ECBA6D1E239DCD003E6328 /* CCCreateCloud.swift in Sources */,
+				F7622FAE2175FCC0000383FF /* ActionSheetItemHandler.swift in Sources */,
 				F758B45E212C569D00515F55 /* ScanCell.swift in Sources */,
 				F70022FE1EC4C9100080073F /* UtilsFramework.m in Sources */,
 				F70022AA1EC4C9100080073F /* AFURLRequestSerialization.m in Sources */,
@@ -4118,6 +4411,7 @@
 				F77B0ED11D118A16002130FE /* Acknowledgements.m in Sources */,
 				F73CC06C1E813DFF006E3047 /* BKPasscodeField.m in Sources */,
 				F77B0ED51D118A16002130FE /* PHAsset+Utility.m in Sources */,
+				F7622FD22175FCC0000383FF /* ActionSheetSelectItem.swift in Sources */,
 				F73B4EFD1F470D9100BBEE4B /* LangHebrewModel.cpp in Sources */,
 				F70022CE1EC4C9100080073F /* OCShareUser.m in Sources */,
 				F77B0ED91D118A16002130FE /* main.m in Sources */,

+ 1 - 1
iOSClient/Brand/File_Provider_Extension.plist

@@ -19,7 +19,7 @@
 	<key>CFBundleShortVersionString</key>
 	<string>2.22.5</string>
 	<key>CFBundleVersion</key>
-	<string>5</string>
+	<string>6</string>
 	<key>NSExtension</key>
 	<dict>
 		<key>NSExtensionFileProviderDocumentGroup</key>

+ 1 - 1
iOSClient/Brand/Notification_Service_Extension.plist

@@ -19,7 +19,7 @@
 	<key>CFBundleShortVersionString</key>
 	<string>2.22.5</string>
 	<key>CFBundleVersion</key>
-	<string>5</string>
+	<string>6</string>
 	<key>NSExtension</key>
 	<dict>
 		<key>NSExtensionPointIdentifier</key>

+ 1 - 1
iOSClient/Brand/Share.plist

@@ -19,7 +19,7 @@
 	<key>CFBundleShortVersionString</key>
 	<string>2.22.5</string>
 	<key>CFBundleVersion</key>
-	<string>5</string>
+	<string>6</string>
 	<key>NSAppTransportSecurity</key>
 	<dict>
 		<key>NSAllowsArbitraryLoads</key>

+ 1 - 1
iOSClient/Brand/iOSClient.plist

@@ -69,7 +69,7 @@
 		</dict>
 	</array>
 	<key>CFBundleVersion</key>
-	<string>5</string>
+	<string>6</string>
 	<key>FIREBASE_ANALYTICS_COLLECTION_DEACTIVATED</key>
 	<true/>
 	<key>Fabric</key>

+ 13 - 1
iOSClient/Trash/NCTrash.swift

@@ -72,7 +72,19 @@ class NCTrash: UIViewController , UICollectionViewDataSource, UICollectionViewDe
     }
     
     func tapMoreItem(with fileID: String) {
-        deleteItem(with: fileID)
+        
+        var items = [ActionSheetItem]()
+        
+        items.append(ActionSheetTitle(title: NSLocalizedString("_delete_selected_files_", comment: "")))
+        items.append(ActionSheetDangerButton(title: NSLocalizedString("_delete_", comment: "")))
+        items.append(ActionSheetCancelButton(title: NSLocalizedString("_cancel_", comment: "")))
+        
+        let actionSheet = ActionSheet(items: items) { sheet, item in
+            if item is ActionSheetDangerButton { self.deleteItem(with: fileID) }
+            if item is ActionSheetCancelButton { print("Cancel buttons has the value `true`") }
+        }
+        
+        actionSheet.present(in: self, from: self.view)
     }
     
     func tapSwitchHeaderMenu() {