SwipeActions.swift 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. //
  2. // Swipe.swift
  3. // Eureka
  4. //
  5. // Created by Marco Betschart on 14.06.17.
  6. // Copyright © 2017 Xmartlabs. All rights reserved.
  7. //
  8. import Foundation
  9. import UIKit
  10. public typealias SwipeActionHandler = (SwipeAction, BaseRow, ((Bool) -> Void)?) -> Void
  11. public class SwipeAction: ContextualAction {
  12. let handler: SwipeActionHandler
  13. let style: Style
  14. public var actionBackgroundColor: UIColor?
  15. public var image: UIImage?
  16. public var title: String?
  17. @available (*, deprecated, message: "Use actionBackgroundColor instead")
  18. public var backgroundColor: UIColor? {
  19. get { return actionBackgroundColor }
  20. set { self.actionBackgroundColor = newValue }
  21. }
  22. public init(style: Style, title: String?, handler: @escaping SwipeActionHandler){
  23. self.style = style
  24. self.title = title
  25. self.handler = handler
  26. }
  27. func contextualAction(forRow: BaseRow) -> ContextualAction {
  28. var action: ContextualAction
  29. if #available(iOS 11, *){
  30. action = UIContextualAction(style: style.contextualStyle as! UIContextualAction.Style, title: title){ [weak self] action, view, completion -> Void in
  31. guard let strongSelf = self else{ return }
  32. strongSelf.handler(strongSelf, forRow) { shouldComplete in
  33. if #available(iOS 13, *) { // starting in iOS 13, completion handler is not removing the row automatically, so we need to remove it ourselves
  34. if shouldComplete && action.style == .destructive {
  35. forRow.section?.remove(at: forRow.indexPath!.row)
  36. }
  37. }
  38. completion(shouldComplete)
  39. }
  40. }
  41. } else {
  42. action = UITableViewRowAction(style: style.contextualStyle as! UITableViewRowAction.Style,title: title){ [weak self] (action, indexPath) -> Void in
  43. guard let strongSelf = self else{ return }
  44. strongSelf.handler(strongSelf, forRow) { _ in
  45. DispatchQueue.main.async {
  46. guard action.style == .destructive else {
  47. forRow.baseCell?.formViewController()?.tableView?.setEditing(false, animated: true)
  48. return
  49. }
  50. forRow.section?.remove(at: indexPath.row)
  51. }
  52. }
  53. }
  54. }
  55. if let color = self.actionBackgroundColor {
  56. action.actionBackgroundColor = color
  57. }
  58. if let image = self.image {
  59. action.image = image
  60. }
  61. return action
  62. }
  63. public enum Style {
  64. case normal
  65. case destructive
  66. var contextualStyle: ContextualStyle {
  67. if #available(iOS 11, *){
  68. switch self{
  69. case .normal:
  70. return UIContextualAction.Style.normal
  71. case .destructive:
  72. return UIContextualAction.Style.destructive
  73. }
  74. } else {
  75. switch self{
  76. case .normal:
  77. return UITableViewRowAction.Style.normal
  78. case .destructive:
  79. return UITableViewRowAction.Style.destructive
  80. }
  81. }
  82. }
  83. }
  84. }
  85. public struct SwipeConfiguration {
  86. unowned var row: BaseRow
  87. init(_ row: BaseRow){
  88. self.row = row
  89. }
  90. public var performsFirstActionWithFullSwipe = false
  91. public var actions: [SwipeAction] = []
  92. }
  93. extension SwipeConfiguration {
  94. @available(iOS 11.0, *)
  95. var contextualConfiguration: UISwipeActionsConfiguration? {
  96. let contextualConfiguration = UISwipeActionsConfiguration(actions: self.contextualActions as! [UIContextualAction])
  97. contextualConfiguration.performsFirstActionWithFullSwipe = self.performsFirstActionWithFullSwipe
  98. return contextualConfiguration
  99. }
  100. var contextualActions: [ContextualAction]{
  101. return self.actions.map { $0.contextualAction(forRow: self.row) }
  102. }
  103. }
  104. protocol ContextualAction {
  105. var actionBackgroundColor: UIColor? { get set }
  106. var image: UIImage? { get set }
  107. var title: String? { get set }
  108. }
  109. extension UITableViewRowAction: ContextualAction {
  110. public var image: UIImage? {
  111. get { return nil }
  112. set { return }
  113. }
  114. public var actionBackgroundColor: UIColor? {
  115. get { return backgroundColor }
  116. set { self.backgroundColor = newValue }
  117. }
  118. }
  119. @available(iOS 11.0, *)
  120. extension UIContextualAction: ContextualAction {
  121. public var actionBackgroundColor: UIColor? {
  122. get { return backgroundColor }
  123. set { self.backgroundColor = newValue }
  124. }
  125. }
  126. public protocol ContextualStyle{}
  127. extension UITableViewRowAction.Style: ContextualStyle {}
  128. @available(iOS 11.0, *)
  129. extension UIContextualAction.Style: ContextualStyle {}