From 2d3bfb07f794bf2c2ed8d3238ae9fe04d4df092f Mon Sep 17 00:00:00 2001 From: Sandin Date: Thu, 3 Sep 2020 11:54:40 +0200 Subject: [PATCH 1/4] check ios14 - add differ via spm to the last version --- Cartfile | 1 - DataSource.xcodeproj/project.pbxproj | 107 ++++++++++-------- .../contents.xcworkspacedata | 2 +- .../xcshareddata/swiftpm/Package.resolved | 16 +++ 4 files changed, 79 insertions(+), 47 deletions(-) delete mode 100644 Cartfile create mode 100644 DataSource.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved diff --git a/Cartfile b/Cartfile deleted file mode 100644 index 83454b0..0000000 --- a/Cartfile +++ /dev/null @@ -1 +0,0 @@ -github "tonyarnold/Differ" ~> 1.4 diff --git a/DataSource.xcodeproj/project.pbxproj b/DataSource.xcodeproj/project.pbxproj index 874137f..a39dbaa 100644 --- a/DataSource.xcodeproj/project.pbxproj +++ b/DataSource.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 52; objects = { /* Begin PBXBuildFile section */ @@ -40,8 +40,6 @@ 39A848691E5E1D9600D7DBC2 /* DataSource.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 395D14A41B90612D00658680 /* DataSource.framework */; }; 39A848751E5E2DEC00D7DBC2 /* DataSource.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 395D14A41B90612D00658680 /* DataSource.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 39B621801E6D757000BE18EE /* DataSource+UITableViewDataSourcePrefetching.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39B6217F1E6D757000BE18EE /* DataSource+UITableViewDataSourcePrefetching.swift */; }; - 39D22FF7221C403C00C12A01 /* Differ.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 39D22FF6221C403C00C12A01 /* Differ.framework */; }; - 39D22FF8221C40BB00C12A01 /* Differ.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 39D22FF6221C403C00C12A01 /* Differ.framework */; }; 39E9E3A81E6566AD00A3C300 /* PersonCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39E9E3A51E6566AD00A3C300 /* PersonCell.swift */; }; 39E9E3A91E6566AD00A3C300 /* TitleCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39E9E3A61E6566AD00A3C300 /* TitleCell.swift */; }; 39E9E3AA1E6566AD00A3C300 /* TitleCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 39E9E3A71E6566AD00A3C300 /* TitleCell.xib */; }; @@ -53,6 +51,7 @@ 4C6076DF21490C80002E8BD1 /* SeparatedSectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C6076DE21490C80002E8BD1 /* SeparatedSectionViewController.swift */; }; 4CA65F60214F952E004F2F19 /* UIView+AutoLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CA65F5F214F952E004F2F19 /* UIView+AutoLayout.swift */; }; 5C61C91820AF0AB0003A08B8 /* SwipeActionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C61C91720AF0AB0003A08B8 /* SwipeActionViewController.swift */; }; + 5FD722022500F36800835AA1 /* Differ in Frameworks */ = {isa = PBXBuildFile; productRef = 5FD722012500F36800835AA1 /* Differ */; }; D8D61BEE21E4DD3E00937D1C /* SeparatorLineViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8D61BED21E4DD3E00937D1C /* SeparatorLineViewModel.swift */; }; D8D61BF021E4E11300937D1C /* SeparatorCustomViewViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8D61BEF21E4E11300937D1C /* SeparatorCustomViewViewModel.swift */; }; /* End PBXBuildFile section */ @@ -130,7 +129,6 @@ 398248A91E5C6DDC00F802D1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 398248AB1E5C6DDC00F802D1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 398248AE1E5C6EFB00F802D1 /* DataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataSource.swift; sourceTree = ""; }; - 398248B31E5C704700F802D1 /* Cartfile */ = {isa = PBXFileReference; lastKnownFileType = text; path = Cartfile; sourceTree = ""; }; 398248B41E5C705000F802D1 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 398248C01E5C7A3500F802D1 /* Row.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Row.swift; sourceTree = ""; }; 398248C21E5C7A4000F802D1 /* Section.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Section.swift; sourceTree = ""; }; @@ -145,7 +143,6 @@ 39A848661E5E1D9600D7DBC2 /* DataSourceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataSourceTests.swift; sourceTree = ""; }; 39A848681E5E1D9600D7DBC2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 39B6217F1E6D757000BE18EE /* DataSource+UITableViewDataSourcePrefetching.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DataSource+UITableViewDataSourcePrefetching.swift"; sourceTree = ""; }; - 39D22FF6221C403C00C12A01 /* Differ.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Differ.framework; path = Carthage/Build/iOS/Differ.framework; sourceTree = ""; }; 39E9E3A51E6566AD00A3C300 /* PersonCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PersonCell.swift; sourceTree = ""; }; 39E9E3A61E6566AD00A3C300 /* TitleCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TitleCell.swift; sourceTree = ""; }; 39E9E3A71E6566AD00A3C300 /* TitleCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = TitleCell.xib; sourceTree = ""; }; @@ -166,7 +163,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 39D22FF8221C40BB00C12A01 /* Differ.framework in Frameworks */, 395D14B91B90612D00658680 /* DataSource.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -175,7 +171,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 39D22FF7221C403C00C12A01 /* Differ.framework in Frameworks */, + 5FD722022500F36800835AA1 /* Differ in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -193,12 +189,10 @@ 395D14731B90610A00658680 = { isa = PBXGroup; children = ( - 398248B31E5C704700F802D1 /* Cartfile */, 398248B41E5C705000F802D1 /* README.md */, 395D14A51B90612D00658680 /* DataSource */, 39A848651E5E1D9600D7DBC2 /* DataSourceTests */, 395D147E1B90610A00658680 /* Example */, - 398248B51E5C707A00F802D1 /* Frameworks */, 395D147D1B90610A00658680 /* Products */, ); sourceTree = ""; @@ -284,14 +278,6 @@ path = Storyboards; sourceTree = ""; }; - 398248B51E5C707A00F802D1 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 39D22FF6221C403C00C12A01 /* Differ.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; 39913AB61E61BBB900623635 /* Utilities */ = { isa = PBXGroup; children = ( @@ -366,7 +352,6 @@ 395D14791B90610A00658680 /* Frameworks */, 395D147A1B90610A00658680 /* Resources */, 395D14BE1B90612D00658680 /* Embed Frameworks */, - 398248B81E5C70B900F802D1 /* Carthage */, ); buildRules = ( ); @@ -392,6 +377,9 @@ dependencies = ( ); name = DataSource; + packageProductDependencies = ( + 5FD722012500F36800835AA1 /* Differ */, + ); productName = DataSource; productReference = 395D14A41B90612D00658680 /* DataSource.framework */; productType = "com.apple.product-type.framework"; @@ -464,6 +452,9 @@ Base, ); mainGroup = 395D14731B90610A00658680; + packageReferences = ( + 5FD722002500F36800835AA1 /* XCRemoteSwiftPackageReference "Differ" */, + ); productRefGroup = 395D147D1B90610A00658680 /* Products */; projectDirPath = ""; projectRoot = ""; @@ -504,24 +495,6 @@ }; /* End PBXResourcesBuildPhase section */ -/* Begin PBXShellScriptBuildPhase section */ - 398248B81E5C70B900F802D1 /* Carthage */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "$(SRCROOT)/Carthage/Build/iOS/Differ.framework", - ); - name = Carthage; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/usr/local/bin/carthage copy-frameworks\n"; - }; -/* End PBXShellScriptBuildPhase section */ - /* Begin PBXSourcesBuildPhase section */ 395D14781B90610A00658680 /* Sources */ = { isa = PBXSourcesBuildPhase; @@ -734,7 +707,10 @@ ); INFOPLIST_FILE = Example/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 11.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); PRODUCT_BUNDLE_IDENTIFIER = com.buchetics.DataSourceExample; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; @@ -756,12 +732,16 @@ ); INFOPLIST_FILE = Example/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 11.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); PRODUCT_BUNDLE_IDENTIFIER = com.buchetics.DataSourceExample; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; SWIFT_VERSION = 5.0; }; name = Release; @@ -785,7 +765,11 @@ ); INFOPLIST_FILE = DataSource/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); PRODUCT_BUNDLE_IDENTIFIER = com.buchetics.DataSource; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -817,12 +801,17 @@ ); INFOPLIST_FILE = DataSource/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); PRODUCT_BUNDLE_IDENTIFIER = com.buchetics.DataSource; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = YES; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; @@ -843,7 +832,11 @@ ); INFOPLIST_FILE = DataSourceTests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 10.2; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); PRODUCT_BUNDLE_IDENTIFIER = com.buchetics.DataSourceTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; @@ -865,10 +858,15 @@ ); INFOPLIST_FILE = DataSourceTests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 10.2; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); PRODUCT_BUNDLE_IDENTIFIER = com.buchetics.DataSourceTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example.app/Example"; }; @@ -914,6 +912,25 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + 5FD722002500F36800835AA1 /* XCRemoteSwiftPackageReference "Differ" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/tonyarnold/Differ"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 1.4.5; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 5FD722012500F36800835AA1 /* Differ */ = { + isa = XCSwiftPackageProductDependency; + package = 5FD722002500F36800835AA1 /* XCRemoteSwiftPackageReference "Differ" */; + productName = Differ; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = 395D14741B90610A00658680 /* Project object */; } diff --git a/DataSource.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/DataSource.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 106019c..919434a 100644 --- a/DataSource.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/DataSource.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/DataSource.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DataSource.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000..4f1abe8 --- /dev/null +++ b/DataSource.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,16 @@ +{ + "object": { + "pins": [ + { + "package": "Differ", + "repositoryURL": "https://github.com/tonyarnold/Differ", + "state": { + "branch": null, + "revision": "4c3eb4d76ad5c14075829397a5741b0badb08dce", + "version": "1.4.5" + } + } + ] + }, + "version": 1 +} From 8085d5ec55b5d54f007ad5f3d96dba9295025dbe Mon Sep 17 00:00:00 2001 From: Sandin Date: Thu, 3 Sep 2020 17:20:00 +0200 Subject: [PATCH 2/4] add context menu --- DataSource/CellDescriptor.swift | 241 ++++++++++-------- .../DataSource+UITableViewDelegate.swift | 65 +++-- DataSource/DataSource.swift | 161 +++++++----- .../Examples/DiffViewController.swift | 65 +++-- 4 files changed, 306 insertions(+), 226 deletions(-) diff --git a/DataSource/CellDescriptor.swift b/DataSource/CellDescriptor.swift index ed9c619..63440dc 100644 --- a/DataSource/CellDescriptor.swift +++ b/DataSource/CellDescriptor.swift @@ -9,24 +9,22 @@ import UIKit public enum SelectionResult { - case deselect case keepSelected } -// MARK - CellDescriptorType +// MARK: - CellDescriptorType public protocol CellDescriptorType { - var rowIdentifier: String { get } var cellIdentifier: String { get } var bundle: Bundle? { get } var cellClass: UITableViewCell.Type { get } - + // UITableViewDataSource var configureClosure: ((RowType, UITableViewCell, IndexPath) -> Void)? { get } - + var canEditClosure: ((RowType, IndexPath) -> Bool)? { get } var canMoveClosure: ((RowType, IndexPath) -> Bool)? { get } var commitEditingClosure: ((RowType, UITableViewCell.EditingStyle, IndexPath) -> Void)? { get } @@ -53,7 +51,7 @@ public protocol CellDescriptorType { var editActionsClosure: ((RowType, IndexPath) -> [UITableViewRowAction]?)? { get } var shouldIndentWhileEditingClosure: ((RowType, IndexPath) -> Bool)? { get } var willBeginEditingClosure: ((RowType, IndexPath) -> Void)? { get } - + var targetIndexPathForMoveClosure: ((RowType, (IndexPath, IndexPath)) -> IndexPath)? { get } var indentationLevelClosure: ((RowType, IndexPath) -> Int)? { get } var shouldShowMenuClosure: ((RowType, IndexPath) -> Bool)? { get } @@ -73,10 +71,14 @@ public protocol CellDescriptorTypeiOS11: CellDescriptorType { var trailingSwipeActionsClosure: ((RowType, IndexPath) -> UISwipeActionsConfiguration?)? { get } } -// MARK - CellDescriptor +@available(iOS 13.0, *) +public protocol CellDescriptorTypeiOS13: CellDescriptorType { + var configurationForMenuAtLocationClosure: ((RowType, IndexPath) -> UIContextMenuConfiguration?)? { get } +} + +// MARK: - CellDescriptor public class CellDescriptor: CellDescriptorType { - public let rowIdentifier: String public let cellIdentifier: String public let bundle: Bundle? @@ -104,7 +106,7 @@ public class CellDescriptor: CellDescriptorType { } return cell } - + // MARK: - UITableViewDataSource // MARK: configure @@ -112,7 +114,7 @@ public class CellDescriptor: CellDescriptorType { public private(set) var configureClosure: ((RowType, UITableViewCell, IndexPath) -> Void)? public func configure(_ closure: @escaping (Item, Cell, IndexPath) -> Void) -> CellDescriptor { - configureClosure = { [unowned self] (row, cell, indexPath) in + configureClosure = { [unowned self] row, cell, indexPath in closure(self.typedItem(row), self.typedCell(cell), indexPath) } return self @@ -123,14 +125,14 @@ public class CellDescriptor: CellDescriptorType { public private(set) var canEditClosure: ((RowType, IndexPath) -> Bool)? public func canEdit(_ closure: @escaping (Item, IndexPath) -> Bool) -> CellDescriptor { - canEditClosure = { [unowned self] (row, indexPath) in + canEditClosure = { [unowned self] row, indexPath in closure(self.typedItem(row), indexPath) } return self } public func canEdit(_ closure: @escaping () -> Bool) -> CellDescriptor { - canEditClosure = { (_, _) in + canEditClosure = { _, _ in closure() } return self @@ -141,14 +143,14 @@ public class CellDescriptor: CellDescriptorType { public private(set) var canMoveClosure: ((RowType, IndexPath) -> Bool)? public func canMove(_ closure: @escaping (Item, IndexPath) -> Bool) -> CellDescriptor { - canMoveClosure = { [unowned self] (row, indexPath) in + canMoveClosure = { [unowned self] row, indexPath in closure(self.typedItem(row), indexPath) } return self } public func canMove(_ closure: @escaping () -> Bool) -> CellDescriptor { - canMoveClosure = { (_, _) in + canMoveClosure = { _, _ in closure() } return self @@ -159,15 +161,15 @@ public class CellDescriptor: CellDescriptorType { public private(set) var heightClosure: ((RowType, IndexPath) -> CGFloat)? public func height(_ closure: @escaping (Item, IndexPath) -> CGFloat) -> CellDescriptor { - heightClosure = { [unowned self] (row, indexPath) in - return closure(self.typedItem(row), indexPath) + heightClosure = { [unowned self] row, indexPath in + closure(self.typedItem(row), indexPath) } return self } public func height(_ closure: @escaping () -> CGFloat) -> CellDescriptor { - heightClosure = { (_, _) in - return closure() + heightClosure = { _, _ in + closure() } return self } @@ -177,15 +179,15 @@ public class CellDescriptor: CellDescriptorType { public private(set) var estimatedHeightClosure: ((RowType, IndexPath) -> CGFloat)? public func estimatedHeight(_ closure: @escaping (Item, IndexPath) -> CGFloat) -> CellDescriptor { - estimatedHeightClosure = { [unowned self] (row, indexPath) in - return closure(self.typedItem(row), indexPath) + estimatedHeightClosure = { [unowned self] row, indexPath in + closure(self.typedItem(row), indexPath) } return self } public func estimatedHeight(_ closure: @escaping () -> CGFloat) -> CellDescriptor { - estimatedHeightClosure = { (_, _) in - return closure() + estimatedHeightClosure = { _, _ in + closure() } return self } @@ -195,8 +197,8 @@ public class CellDescriptor: CellDescriptorType { public private(set) var commitEditingClosure: ((RowType, UITableViewCell.EditingStyle, IndexPath) -> Void)? public func commitEditing(_ closure: @escaping (Item, UITableViewCell.EditingStyle, IndexPath) -> Void) -> CellDescriptor { - commitEditingClosure = { [unowned self] (row, editingStyle, indexPath) in - return closure(self.typedItem(row), editingStyle, indexPath) + commitEditingClosure = { [unowned self] row, editingStyle, indexPath in + closure(self.typedItem(row), editingStyle, indexPath) } return self } @@ -206,8 +208,8 @@ public class CellDescriptor: CellDescriptorType { public private(set) var moveRowClosure: ((RowType, (IndexPath, IndexPath)) -> Void)? public func moveRow(_ closure: @escaping (Item, (IndexPath, IndexPath)) -> Void) -> CellDescriptor { - moveRowClosure = { [unowned self] (row, indexPaths) in - return closure(self.typedItem(row), indexPaths) + moveRowClosure = { [unowned self] row, indexPaths in + closure(self.typedItem(row), indexPaths) } return self } @@ -219,15 +221,15 @@ public class CellDescriptor: CellDescriptorType { public private(set) var shouldHighlightClosure: ((RowType, IndexPath) -> Bool)? public func shouldHighlight(_ closure: @escaping (Item, IndexPath) -> Bool) -> CellDescriptor { - shouldHighlightClosure = { [unowned self] (row, indexPath) in - return closure(self.typedItem(row), indexPath) + shouldHighlightClosure = { [unowned self] row, indexPath in + closure(self.typedItem(row), indexPath) } return self } public func shouldHighlight(_ closure: @escaping () -> Bool) -> CellDescriptor { - shouldHighlightClosure = { (_, _) in - return closure() + shouldHighlightClosure = { _, _ in + closure() } return self } @@ -237,15 +239,15 @@ public class CellDescriptor: CellDescriptorType { public private(set) var didHighlightClosure: ((RowType, IndexPath) -> Void)? public func didHighlight(_ closure: @escaping (Item, IndexPath) -> Void) -> CellDescriptor { - didHighlightClosure = { [unowned self] (row, indexPath) in - return closure(self.typedItem(row), indexPath) + didHighlightClosure = { [unowned self] row, indexPath in + closure(self.typedItem(row), indexPath) } return self } public func didHighlight(_ closure: @escaping () -> Void) -> CellDescriptor { - didHighlightClosure = { (_, _) in - return closure() + didHighlightClosure = { _, _ in + closure() } return self } @@ -255,15 +257,15 @@ public class CellDescriptor: CellDescriptorType { public private(set) var didUnhighlightClosure: ((RowType, IndexPath) -> Void)? public func didUnhighlight(_ closure: @escaping (Item, IndexPath) -> Void) -> CellDescriptor { - didUnhighlightClosure = { [unowned self] (row, indexPath) in - return closure(self.typedItem(row), indexPath) + didUnhighlightClosure = { [unowned self] row, indexPath in + closure(self.typedItem(row), indexPath) } return self } public func didUnhighlight(_ closure: @escaping () -> Void) -> CellDescriptor { - didUnhighlightClosure = { (_, _) in - return closure() + didUnhighlightClosure = { _, _ in + closure() } return self } @@ -273,15 +275,15 @@ public class CellDescriptor: CellDescriptorType { public private(set) var willSelectClosure: ((RowType, IndexPath) -> IndexPath?)? public func willSelect(_ closure: @escaping (Item, IndexPath) -> IndexPath?) -> CellDescriptor { - willSelectClosure = { [unowned self] (row, indexPath) in - return closure(self.typedItem(row), indexPath) + willSelectClosure = { [unowned self] row, indexPath in + closure(self.typedItem(row), indexPath) } return self } public func willSelect(_ closure: @escaping () -> IndexPath?) -> CellDescriptor { - willSelectClosure = { (_, _) in - return closure() + willSelectClosure = { _, _ in + closure() } return self } @@ -291,15 +293,15 @@ public class CellDescriptor: CellDescriptorType { public private(set) var willDeselectClosure: ((RowType, IndexPath) -> IndexPath?)? public func willDeselect(_ closure: @escaping (Item, IndexPath) -> IndexPath?) -> CellDescriptor { - willDeselectClosure = { [unowned self] (row, indexPath) in - return closure(self.typedItem(row), indexPath) + willDeselectClosure = { [unowned self] row, indexPath in + closure(self.typedItem(row), indexPath) } return self } public func willDeselect(_ closure: @escaping () -> IndexPath?) -> CellDescriptor { - willDeselectClosure = { (_, _) in - return closure() + willDeselectClosure = { _, _ in + closure() } return self } @@ -309,15 +311,15 @@ public class CellDescriptor: CellDescriptorType { public private(set) var didSelectClosure: ((RowType, IndexPath) -> SelectionResult)? public func didSelect(_ closure: @escaping (Item, IndexPath) -> SelectionResult) -> CellDescriptor { - didSelectClosure = { [unowned self] (row, indexPath) in - return closure(self.typedItem(row), indexPath) + didSelectClosure = { [unowned self] row, indexPath in + closure(self.typedItem(row), indexPath) } return self } public func didSelect(_ closure: @escaping () -> SelectionResult) -> CellDescriptor { - didSelectClosure = { (_, _) in - return closure() + didSelectClosure = { _, _ in + closure() } return self } @@ -327,15 +329,15 @@ public class CellDescriptor: CellDescriptorType { public private(set) var didDeselectClosure: ((RowType, IndexPath) -> Void)? public func didDeselect(_ closure: @escaping (Item, IndexPath) -> Void) -> CellDescriptor { - didDeselectClosure = { [unowned self] (row, indexPath) in - return closure(self.typedItem(row), indexPath) + didDeselectClosure = { [unowned self] row, indexPath in + closure(self.typedItem(row), indexPath) } return self } public func didDeselect(_ closure: @escaping () -> Void) -> CellDescriptor { - didDeselectClosure = { (_, _) in - return closure() + didDeselectClosure = { _, _ in + closure() } return self } @@ -345,8 +347,8 @@ public class CellDescriptor: CellDescriptorType { public private(set) var willDisplayClosure: ((RowType, UITableViewCell, IndexPath) -> Void)? public func willDisplay(_ closure: @escaping (Item, Cell, IndexPath) -> Void) -> CellDescriptor { - willDisplayClosure = { [unowned self] (row, cell, indexPath) in - return closure(self.typedItem(row), self.typedCell(cell), indexPath) + willDisplayClosure = { [unowned self] row, cell, indexPath in + closure(self.typedItem(row), self.typedCell(cell), indexPath) } return self } @@ -356,15 +358,15 @@ public class CellDescriptor: CellDescriptorType { public private(set) var editingStyleClosure: ((RowType, IndexPath) -> UITableViewCell.EditingStyle)? public func editingStyle(_ closure: @escaping (Item, IndexPath) -> UITableViewCell.EditingStyle) -> CellDescriptor { - editingStyleClosure = { [unowned self] (row, indexPath) in - return closure(self.typedItem(row), indexPath) + editingStyleClosure = { [unowned self] row, indexPath in + closure(self.typedItem(row), indexPath) } return self } public func editingStyle(_ closure: @escaping () -> UITableViewCell.EditingStyle) -> CellDescriptor { - editingStyleClosure = { (_, _) in - return closure() + editingStyleClosure = { _, _ in + closure() } return self } @@ -374,15 +376,15 @@ public class CellDescriptor: CellDescriptorType { public private(set) var titleForDeleteConfirmationButtonClosure: ((RowType, IndexPath) -> String?)? public func titleForDeleteConfirmationButton(_ closure: @escaping (Item, IndexPath) -> String?) -> CellDescriptor { - titleForDeleteConfirmationButtonClosure = { [unowned self] (row, indexPath) in - return closure(self.typedItem(row), indexPath) + titleForDeleteConfirmationButtonClosure = { [unowned self] row, indexPath in + closure(self.typedItem(row), indexPath) } return self } public func titleForDeleteConfirmationButton(_ closure: @escaping () -> String?) -> CellDescriptor { - titleForDeleteConfirmationButtonClosure = { (_, _) in - return closure() + titleForDeleteConfirmationButtonClosure = { _, _ in + closure() } return self } @@ -392,20 +394,24 @@ public class CellDescriptor: CellDescriptorType { private var _leadingSwipeActionsClosure: ((RowType, IndexPath) -> Any?)? private var _trailingSwipeActionsClosure: ((RowType, IndexPath) -> Any?)? + // MARK: contextMenu + + public var _configurationForMenuAtLocationClosure: ((RowType, IndexPath) -> Any)? + // MARK: editActions public private(set) var editActionsClosure: ((RowType, IndexPath) -> [UITableViewRowAction]?)? public func editActions(_ closure: @escaping (Item, IndexPath) -> [UITableViewRowAction]?) -> CellDescriptor { - editActionsClosure = { [unowned self] (row, indexPath) in - return closure(self.typedItem(row), indexPath) + editActionsClosure = { [unowned self] row, indexPath in + closure(self.typedItem(row), indexPath) } return self } public func editActions(_ closure: @escaping () -> [UITableViewRowAction]?) -> CellDescriptor { - editActionsClosure = { (_, _) in - return closure() + editActionsClosure = { _, _ in + closure() } return self } @@ -415,15 +421,15 @@ public class CellDescriptor: CellDescriptorType { public private(set) var shouldIndentWhileEditingClosure: ((RowType, IndexPath) -> Bool)? public func shouldIndentWhileEditing(_ closure: @escaping (Item, IndexPath) -> Bool) -> CellDescriptor { - shouldIndentWhileEditingClosure = { [unowned self] (row, indexPath) in - return closure(self.typedItem(row), indexPath) + shouldIndentWhileEditingClosure = { [unowned self] row, indexPath in + closure(self.typedItem(row), indexPath) } return self } public func shouldIndentWhileEditing(_ closure: @escaping () -> Bool) -> CellDescriptor { - shouldIndentWhileEditingClosure = { (_, _) in - return closure() + shouldIndentWhileEditingClosure = { _, _ in + closure() } return self } @@ -433,14 +439,14 @@ public class CellDescriptor: CellDescriptorType { public private(set) var willBeginEditingClosure: ((RowType, IndexPath) -> Void)? public func willBeginEditing(_ closure: @escaping (Item, IndexPath) -> Void) -> CellDescriptor { - willBeginEditingClosure = { [unowned self] (row, indexPath) in + willBeginEditingClosure = { [unowned self] row, indexPath in closure(self.typedItem(row), indexPath) } return self } public func willBeginEditing(_ closure: @escaping () -> Void) -> CellDescriptor { - willBeginEditingClosure = { (_, _) in + willBeginEditingClosure = { _, _ in closure() } return self @@ -451,7 +457,7 @@ public class CellDescriptor: CellDescriptorType { public private(set) var targetIndexPathForMoveClosure: ((RowType, (IndexPath, IndexPath)) -> IndexPath)? public func targetIndexPathForMove(_ closure: @escaping (Item, (IndexPath, IndexPath)) -> IndexPath) -> CellDescriptor { - targetIndexPathForMoveClosure = { [unowned self] (row, indexPaths) in + targetIndexPathForMoveClosure = { [unowned self] row, indexPaths in closure(self.typedItem(row), indexPaths) } return self @@ -462,14 +468,14 @@ public class CellDescriptor: CellDescriptorType { public private(set) var indentationLevelClosure: ((RowType, IndexPath) -> Int)? public func indentationLevel(_ closure: @escaping (Item, IndexPath) -> Int) -> CellDescriptor { - indentationLevelClosure = { [unowned self] (row, indexPath) in + indentationLevelClosure = { [unowned self] row, indexPath in closure(self.typedItem(row), indexPath) } return self } public func indentationLevel(_ closure: @escaping () -> Int) -> CellDescriptor { - indentationLevelClosure = { (_, _) in + indentationLevelClosure = { _, _ in closure() } return self @@ -480,14 +486,14 @@ public class CellDescriptor: CellDescriptorType { public private(set) var shouldShowMenuClosure: ((RowType, IndexPath) -> Bool)? public func shouldShowMenu(_ closure: @escaping (Item, IndexPath) -> Bool) -> CellDescriptor { - shouldShowMenuClosure = { [unowned self] (row, indexPath) in + shouldShowMenuClosure = { [unowned self] row, indexPath in closure(self.typedItem(row), indexPath) } return self } public func shouldShowMenu(_ closure: @escaping () -> Bool) -> CellDescriptor { - shouldShowMenuClosure = { (_, _) in + shouldShowMenuClosure = { _, _ in closure() } return self @@ -498,14 +504,14 @@ public class CellDescriptor: CellDescriptorType { public private(set) var canPerformActionClosure: ((RowType, Selector, Any?, IndexPath) -> Bool)? public func canPerformAction(_ closure: @escaping (Item, Selector, Any?, IndexPath) -> Bool) -> CellDescriptor { - canPerformActionClosure = { [unowned self] (row, selector, sender, indexPath) in + canPerformActionClosure = { [unowned self] row, selector, sender, indexPath in closure(self.typedItem(row), selector, sender, indexPath) } return self } public func canPerformAction(_ closure: @escaping (Selector, Any?) -> Bool) -> CellDescriptor { - canPerformActionClosure = { (_, selector, sender, _) in + canPerformActionClosure = { _, selector, sender, _ in closure(selector, sender) } return self @@ -516,14 +522,14 @@ public class CellDescriptor: CellDescriptorType { public private(set) var performActionClosure: ((RowType, Selector, Any?, IndexPath) -> Void)? public func performAction(_ closure: @escaping (Item, Selector, Any?, IndexPath) -> Void) -> CellDescriptor { - performActionClosure = { [unowned self] (row, selector, sender, indexPath) in + performActionClosure = { [unowned self] row, selector, sender, indexPath in closure(self.typedItem(row), selector, sender, indexPath) } return self } public func performAction(_ closure: @escaping (Selector, Any?) -> Void) -> CellDescriptor { - performActionClosure = { (_, selector, sender, _) in + performActionClosure = { _, selector, sender, _ in closure(selector, sender) } return self @@ -534,14 +540,14 @@ public class CellDescriptor: CellDescriptorType { public private(set) var canFocusClosure: ((RowType, IndexPath) -> Bool)? public func canFocus(_ closure: @escaping (Item, IndexPath) -> Bool) -> CellDescriptor { - canFocusClosure = { [unowned self] (row, indexPath) in + canFocusClosure = { [unowned self] row, indexPath in closure(self.typedItem(row), indexPath) } return self } public func canFocus(_ closure: @escaping () -> Bool) -> CellDescriptor { - canFocusClosure = { (_, _) in + canFocusClosure = { _, _ in closure() } return self @@ -554,14 +560,14 @@ public class CellDescriptor: CellDescriptorType { public private(set) var isHiddenClosure: ((RowType, IndexPath) -> Bool)? public func isHidden(_ closure: @escaping (Item, IndexPath) -> Bool) -> CellDescriptor { - isHiddenClosure = { [unowned self] (row, indexPath) in + isHiddenClosure = { [unowned self] row, indexPath in closure(self.typedItem(row), indexPath) } return self } public func isHidden(_ closure: @escaping () -> Bool) -> CellDescriptor { - isHiddenClosure = { (_, _) in + isHiddenClosure = { _, _ in closure() } return self @@ -572,7 +578,7 @@ public class CellDescriptor: CellDescriptorType { public private(set) var updateClosure: ((RowType, UITableViewCell, IndexPath) -> Void)? public func update(_ closure: @escaping (Item, Cell, IndexPath) -> Void) -> CellDescriptor { - updateClosure = { [unowned self] (row, cell, indexPath) in + updateClosure = { [unowned self] row, cell, indexPath in closure(self.typedItem(row), self.typedCell(cell), indexPath) } return self @@ -581,41 +587,36 @@ public class CellDescriptor: CellDescriptorType { @available(iOS 11, *) extension CellDescriptor: CellDescriptorTypeiOS11 { - public var leadingSwipeActionsClosure: ((RowType, IndexPath) -> UISwipeActionsConfiguration?)? { - get { - if _leadingSwipeActionsClosure == nil { - return nil - } - - return { [weak self] (rowType, indexPath) in - return self?._leadingSwipeActionsClosure?(rowType, indexPath) as? UISwipeActionsConfiguration - } + if _leadingSwipeActionsClosure == nil { + return nil + } + + return { [weak self] rowType, indexPath in + self?._leadingSwipeActionsClosure?(rowType, indexPath) as? UISwipeActionsConfiguration } } public var trailingSwipeActionsClosure: ((RowType, IndexPath) -> UISwipeActionsConfiguration?)? { - get { - if _trailingSwipeActionsClosure == nil { - return nil - } - - return { [weak self] (rowType, indexPath) in - return self?._trailingSwipeActionsClosure?(rowType, indexPath) as? UISwipeActionsConfiguration - } + if _trailingSwipeActionsClosure == nil { + return nil + } + + return { [weak self] rowType, indexPath in + self?._trailingSwipeActionsClosure?(rowType, indexPath) as? UISwipeActionsConfiguration } } public func leadingSwipeAction(_ closure: @escaping ((Item, IndexPath) -> UISwipeActionsConfiguration?)) -> CellDescriptor { - _leadingSwipeActionsClosure = { [unowned self] (row, indexPath) in - return closure(self.typedItem(row), indexPath) + _leadingSwipeActionsClosure = { [unowned self] row, indexPath in + closure(self.typedItem(row), indexPath) } return self } - + public func trailingSwipeAction(_ closure: @escaping ((Item, IndexPath) -> UISwipeActionsConfiguration?)) -> CellDescriptor { - _trailingSwipeActionsClosure = { [unowned self] (row, indexPath) in - return closure(self.typedItem(row), indexPath) + _trailingSwipeActionsClosure = { [unowned self] row, indexPath in + closure(self.typedItem(row), indexPath) } return self } @@ -628,3 +629,23 @@ extension CellDescriptor: CellDescriptorTypeiOS11 { return _trailingSwipeActionsClosure != nil } } + +@available(iOS 13, *) +extension CellDescriptor: CellDescriptorTypeiOS13 { + public var configurationForMenuAtLocationClosure: ((RowType, IndexPath) -> UIContextMenuConfiguration?)? { + if _configurationForMenuAtLocationClosure == nil { + return nil + } + + return { [weak self] rowType, indexPath in + self?._configurationForMenuAtLocationClosure?(rowType, indexPath) as? UIContextMenuConfiguration + } + } + + public func configurationForMenuAtLocation(_ closure: @escaping ((Item, IndexPath) -> UIContextMenuConfiguration)) -> CellDescriptor { + _configurationForMenuAtLocationClosure = { [unowned self] row, indexPath in + closure(self.typedItem(row), indexPath) + } + return self + } +} diff --git a/DataSource/DataSource+UITableViewDelegate.swift b/DataSource/DataSource+UITableViewDelegate.swift index 9291a76..16b1eed 100644 --- a/DataSource/DataSource+UITableViewDelegate.swift +++ b/DataSource/DataSource+UITableViewDelegate.swift @@ -6,11 +6,10 @@ // Copyright © 2017 aaa - all about apps GmbH. All rights reserved. // -import UIKit import Differ +import UIKit extension DataSource: UITableViewDelegate { - // MARK: Highlighting public func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool { @@ -42,7 +41,7 @@ extension DataSource: UITableViewDelegate { closure(visibleRow(at: indexPath), indexPath) return } - + fallbackDelegate?.tableView?(tableView, didUnhighlightRowAt: indexPath) } @@ -73,7 +72,6 @@ extension DataSource: UITableViewDelegate { public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let cellDescriptor = self.cellDescriptor(at: indexPath) - if let closure = cellDescriptor.didSelectClosure ?? didSelect { let selectionResult = closure(visibleRow(at: indexPath), indexPath) @@ -151,13 +149,13 @@ extension DataSource: UITableViewDelegate { return fallbackDelegate?.tableView?(tableView, heightForRowAt: indexPath) ?? tableView.rowHeight } - + public func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat { let index = indexPath.section let section = visibleSection(at: index) - // Do not get the CellDescriptor if we are dealing with a LazySection because it would instaniate all the rows, - // i.e. estimatedHeightClosure will not be called for LazySections. Instead, use the estimatedHeight on the + // Do not get the CellDescriptor if we are dealing with a LazySection because it would instantiate all the rows, + // i.e. estimatedHeightClosure will not be called for LazySections. Instead, use the estimatedHeight on the // DataSource, the fallback delegate or a constant. if !(section is LazySectionType) { @@ -185,12 +183,12 @@ extension DataSource: UITableViewDelegate { public func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { let sectionDescriptor = self.sectionDescriptor(at: section) - + if let closure = sectionDescriptor?.headerHeightClosure ?? sectionHeaderHeight { return closure(visibleSection(at: section), section).floatValue(for: tableView.style) } - if let result = fallbackDelegate?.tableView?(tableView, heightForHeaderInSection: section) { + if let result = fallbackDelegate?.tableView?(tableView, heightForHeaderInSection: section) { return result } @@ -259,7 +257,7 @@ extension DataSource: UITableViewDelegate { return } - fallbackDelegate?.tableView?(tableView, willDisplay:cell, forRowAt:indexPath) + fallbackDelegate?.tableView?(tableView, willDisplay: cell, forRowAt: indexPath) } public func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) { @@ -270,7 +268,7 @@ extension DataSource: UITableViewDelegate { return } - fallbackDelegate?.tableView?(tableView, willDisplayHeaderView:view, forSection:section) + fallbackDelegate?.tableView?(tableView, willDisplayHeaderView: view, forSection: section) } public func tableView(_ tableView: UITableView, willDisplayFooterView view: UIView, forSection section: Int) { @@ -281,7 +279,7 @@ extension DataSource: UITableViewDelegate { return } - fallbackDelegate?.tableView?(tableView, willDisplayFooterView:view, forSection:section) + fallbackDelegate?.tableView?(tableView, willDisplayFooterView: view, forSection: section) } // the didEnd delegate methods are only supported on a "fallback" level as we may not have the row or section @@ -293,7 +291,7 @@ extension DataSource: UITableViewDelegate { return } - fallbackDelegate?.tableView?(tableView, didEndDisplaying:cell, forRowAt:indexPath) + fallbackDelegate?.tableView?(tableView, didEndDisplaying: cell, forRowAt: indexPath) } public func tableView(_ tableView: UITableView, didEndDisplayingHeaderView view: UIView, forSection section: Int) { @@ -302,7 +300,7 @@ extension DataSource: UITableViewDelegate { return } - fallbackDelegate?.tableView?(tableView, didEndDisplayingHeaderView:view, forSection:section) + fallbackDelegate?.tableView?(tableView, didEndDisplayingHeaderView: view, forSection: section) } public func tableView(_ tableView: UITableView, didEndDisplayingFooterView view: UIView, forSection section: Int) { @@ -311,7 +309,7 @@ extension DataSource: UITableViewDelegate { return } - fallbackDelegate?.tableView?(tableView, didEndDisplayingFooterView:view, forSection:section) + fallbackDelegate?.tableView?(tableView, didEndDisplayingFooterView: view, forSection: section) } // MARK: Editing @@ -323,7 +321,7 @@ extension DataSource: UITableViewDelegate { return closure(visibleRow(at: indexPath), indexPath) } - if let result = fallbackDelegate?.tableView?(tableView, editingStyleForRowAt:indexPath) { + if let result = fallbackDelegate?.tableView?(tableView, editingStyleForRowAt: indexPath) { return result } @@ -341,7 +339,7 @@ extension DataSource: UITableViewDelegate { return closure(visibleRow(at: indexPath), indexPath) } - return fallbackDelegate?.tableView?(tableView, titleForDeleteConfirmationButtonForRowAt:indexPath) + return fallbackDelegate?.tableView?(tableView, titleForDeleteConfirmationButtonForRowAt: indexPath) } public func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? { @@ -351,7 +349,7 @@ extension DataSource: UITableViewDelegate { return closure(visibleRow(at: indexPath), indexPath) } - return fallbackDelegate?.tableView?(tableView, editActionsForRowAt:indexPath) + return fallbackDelegate?.tableView?(tableView, editActionsForRowAt: indexPath) } public func tableView(_ tableView: UITableView, shouldIndentWhileEditingRowAt indexPath: IndexPath) -> Bool { @@ -361,7 +359,7 @@ extension DataSource: UITableViewDelegate { return closure(visibleRow(at: indexPath), indexPath) } - return fallbackDelegate?.tableView?(tableView, shouldIndentWhileEditingRowAt:indexPath) + return fallbackDelegate?.tableView?(tableView, shouldIndentWhileEditingRowAt: indexPath) ?? true } @@ -373,7 +371,7 @@ extension DataSource: UITableViewDelegate { return } - fallbackDelegate?.tableView?(tableView, willBeginEditingRowAt:indexPath) + fallbackDelegate?.tableView?(tableView, willBeginEditingRowAt: indexPath) } public func tableView(_ tableView: UITableView, didEndEditingRowAt indexPath: IndexPath?) { @@ -382,9 +380,9 @@ extension DataSource: UITableViewDelegate { return } - fallbackDelegate?.tableView?(tableView, didEndEditingRowAt:indexPath) + fallbackDelegate?.tableView?(tableView, didEndEditingRowAt: indexPath) } - + // MARK: Moving & Reordering public func tableView(_ tableView: UITableView, targetIndexPathForMoveFromRowAt sourceIndexPath: IndexPath, toProposedIndexPath proposedDestinationIndexPath: IndexPath) -> IndexPath { @@ -394,11 +392,10 @@ extension DataSource: UITableViewDelegate { return closure(visibleRow(at: sourceIndexPath), (sourceIndexPath, proposedDestinationIndexPath)) } - return fallbackDelegate?.tableView?(tableView, targetIndexPathForMoveFromRowAt:sourceIndexPath, toProposedIndexPath: proposedDestinationIndexPath) + return fallbackDelegate?.tableView?(tableView, targetIndexPathForMoveFromRowAt: sourceIndexPath, toProposedIndexPath: proposedDestinationIndexPath) ?? proposedDestinationIndexPath } - // MARK: Indentation public func tableView(_ tableView: UITableView, indentationLevelForRowAt indexPath: IndexPath) -> Int { @@ -450,23 +447,22 @@ extension DataSource: UITableViewDelegate { // MARK: Focus public func tableView(_ tableView: UITableView, canFocusRowAt indexPath: IndexPath) -> Bool { - return fallbackDelegate?.tableView?(tableView, canFocusRowAt:indexPath) + return fallbackDelegate?.tableView?(tableView, canFocusRowAt: indexPath) ?? true } public func tableView(_ tableView: UITableView, shouldUpdateFocusIn context: UITableViewFocusUpdateContext) -> Bool { - return fallbackDelegate?.tableView?(tableView, shouldUpdateFocusIn:context) + return fallbackDelegate?.tableView?(tableView, shouldUpdateFocusIn: context) ?? true } public func tableView(_ tableView: UITableView, didUpdateFocusIn context: UITableViewFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) { - fallbackDelegate?.tableView?(tableView, didUpdateFocusIn:context, with:coordinator) + fallbackDelegate?.tableView?(tableView, didUpdateFocusIn: context, with: coordinator) } public func indexPathForPreferredFocusedView(in tableView: UITableView) -> IndexPath? { return fallbackDelegate?.indexPathForPreferredFocusedView?(in: tableView) } - } @available(iOS 11,*) @@ -489,3 +485,16 @@ extension DataSource { } } } + +@available(iOS 13,*) +extension DataSource { + public func tableView(_ tableView: UITableView, contextMenuConfigurationForRowAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? { + let cellDescriptor = self.cellDescriptor(at: indexPath) as? CellDescriptorTypeiOS13 + + if let closure = cellDescriptor?.configurationForMenuAtLocationClosure { + return closure(visibleRow(at: indexPath), indexPath) + } else { + return fallbackDelegate?.tableView?(tableView, contextMenuConfigurationForRowAt: indexPath, point: CGPoint(x: 0, y: 0)) + } + } +} diff --git a/DataSource/DataSource.swift b/DataSource/DataSource.swift index 7b8d2ce..f88f379 100644 --- a/DataSource/DataSource.swift +++ b/DataSource/DataSource.swift @@ -6,88 +6,90 @@ // Copyright © 2017 aaa - all about apps GmbH. All rights reserved. // -import UIKit import Differ +import UIKit public class DataSource: NSObject { - public var sections: [SectionType] = [] public internal(set) var visibleSections: [SectionType] = [] // MARK: UITableViewDataSource - public var configure: ((RowType, UITableViewCell, IndexPath) -> Void)? = nil - public var canEdit: ((RowType, IndexPath) -> Bool)? = nil - public var canMove: ((RowType, IndexPath) -> Bool)? = nil - public var sectionIndexTitles: (() -> [String]?)? = nil - public var sectionForSectionIndex: ((String, Int) -> Int)? = nil - public var commitEditing: ((RowType, UITableViewCell.EditingStyle, IndexPath) -> Void)? = nil - public var moveRow: ((RowType, (IndexPath, IndexPath)) -> Void)? = nil + public var configure: ((RowType, UITableViewCell, IndexPath) -> Void)? + public var canEdit: ((RowType, IndexPath) -> Bool)? + public var canMove: ((RowType, IndexPath) -> Bool)? + public var sectionIndexTitles: (() -> [String]?)? + public var sectionForSectionIndex: ((String, Int) -> Int)? + public var commitEditing: ((RowType, UITableViewCell.EditingStyle, IndexPath) -> Void)? + public var moveRow: ((RowType, (IndexPath, IndexPath)) -> Void)? - public var fallbackDataSource: UITableViewDataSource? = nil + public var fallbackDataSource: UITableViewDataSource? // MARK: UITableViewDelegate - public var height: ((RowType, IndexPath) -> CGFloat)? = nil + public var height: ((RowType, IndexPath) -> CGFloat)? // no RowType parameter for estimatedHeight because we do not want to potentially instantiate // a LazyRow just to get the height estimate - public var estimatedHeight: ((IndexPath) -> CGFloat)? = nil + public var estimatedHeight: ((IndexPath) -> CGFloat)? - public var shouldHighlight: ((RowType, IndexPath) -> Bool)? = nil - public var didHighlight: ((RowType, IndexPath) -> Void)? = nil - public var didUnhighlight: ((RowType, IndexPath) -> Void)? = nil + public var shouldHighlight: ((RowType, IndexPath) -> Bool)? + public var didHighlight: ((RowType, IndexPath) -> Void)? + public var didUnhighlight: ((RowType, IndexPath) -> Void)? - public var willSelect: ((RowType, IndexPath) -> IndexPath?)? = nil - public var willDeselect: ((RowType, IndexPath) -> IndexPath?)? = nil - public var didSelect: ((RowType, IndexPath) -> SelectionResult)? = nil - public var didDeselect: ((RowType, IndexPath) -> Void)? = nil + public var willSelect: ((RowType, IndexPath) -> IndexPath?)? + public var willDeselect: ((RowType, IndexPath) -> IndexPath?)? + public var didSelect: ((RowType, IndexPath) -> SelectionResult)? + public var didDeselect: ((RowType, IndexPath) -> Void)? - public var willDisplay: ((RowType, UITableViewCell, IndexPath) -> Void)? = nil - public var didEndDisplaying: ((UITableViewCell, IndexPath) -> Void)? = nil + public var willDisplay: ((RowType, UITableViewCell, IndexPath) -> Void)? + public var didEndDisplaying: ((UITableViewCell, IndexPath) -> Void)? - public var editingStyle: ((RowType, IndexPath) -> UITableViewCell.EditingStyle)? = nil - public var titleForDeleteConfirmationButton: ((RowType, IndexPath) -> String?)? = nil - public var editActions: ((RowType, IndexPath) -> [UITableViewRowAction]?)? = nil - public var shouldIndentWhileEditing: ((RowType, IndexPath) -> Bool)? = nil - public var willBeginEditing: ((RowType, IndexPath) -> Void)? = nil - public var didEndEditing: ((IndexPath?) -> Void)? = nil + public var editingStyle: ((RowType, IndexPath) -> UITableViewCell.EditingStyle)? + public var titleForDeleteConfirmationButton: ((RowType, IndexPath) -> String?)? + public var editActions: ((RowType, IndexPath) -> [UITableViewRowAction]?)? + public var shouldIndentWhileEditing: ((RowType, IndexPath) -> Bool)? + public var willBeginEditing: ((RowType, IndexPath) -> Void)? + public var didEndEditing: ((IndexPath?) -> Void)? - public var sectionHeader: ((SectionType, Int) -> HeaderFooter)? = nil - public var sectionFooter: ((SectionType, Int) -> HeaderFooter)? = nil + public var sectionHeader: ((SectionType, Int) -> HeaderFooter)? + public var sectionFooter: ((SectionType, Int) -> HeaderFooter)? - public var sectionHeaderHeight: ((SectionType, Int) -> SectionHeight)? = nil - public var sectionFooterHeight: ((SectionType, Int) -> SectionHeight)? = nil + public var sectionHeaderHeight: ((SectionType, Int) -> SectionHeight)? + public var sectionFooterHeight: ((SectionType, Int) -> SectionHeight)? - public var willDisplaySectionHeader: ((SectionType, UIView, Int) -> Void)? = nil - public var willDisplaySectionFooter: ((SectionType, UIView, Int) -> Void)? = nil + public var willDisplaySectionHeader: ((SectionType, UIView, Int) -> Void)? + public var willDisplaySectionFooter: ((SectionType, UIView, Int) -> Void)? - public var didEndDisplayingSectionHeader: ((UIView, Int) -> Void)? = nil - public var didEndDisplayingSectionFooter: ((UIView, Int) -> Void)? = nil + public var didEndDisplayingSectionHeader: ((UIView, Int) -> Void)? + public var didEndDisplayingSectionFooter: ((UIView, Int) -> Void)? - public var targetIndexPathForMove: ((RowType, (IndexPath, IndexPath)) -> IndexPath)? = nil - public var indentationLevel: ((RowType, IndexPath) -> Int)? = nil - public var shouldShowMenu: ((RowType, IndexPath) -> Bool)? = nil - public var canPerformAction: ((RowType, Selector, Any?, IndexPath) -> Bool)? = nil - public var performAction: ((RowType, Selector, Any?, IndexPath) -> Void)? = nil - public var canFocus: ((RowType, IndexPath) -> Bool)? = nil + public var targetIndexPathForMove: ((RowType, (IndexPath, IndexPath)) -> IndexPath)? + public var indentationLevel: ((RowType, IndexPath) -> Int)? + public var shouldShowMenu: ((RowType, IndexPath) -> Bool)? + public var canPerformAction: ((RowType, Selector, Any?, IndexPath) -> Bool)? + public var performAction: ((RowType, Selector, Any?, IndexPath) -> Void)? + public var canFocus: ((RowType, IndexPath) -> Bool)? // MARK: Swipe Actions (iOS 11+ only) - private var _leadingSwipeActions: ((RowType, IndexPath) -> Any?)? = nil - private var _trailingSwipeActions: ((RowType, IndexPath) -> Any?)? = nil + + private var _leadingSwipeActions: ((RowType, IndexPath) -> Any?)? + private var _trailingSwipeActions: ((RowType, IndexPath) -> Any?)? + + public var _configurationForMenuAtLocationClosure: ((RowType, IndexPath) -> Any)? // MARK: UITableViewDataSourcePrefetching - public var prefetchRows: (([IndexPath]) -> Void)? = nil - public var cancelPrefetching: (([IndexPath]) -> Void)? = nil + public var prefetchRows: (([IndexPath]) -> Void)? + public var cancelPrefetching: (([IndexPath]) -> Void)? - public weak var fallbackDataSourcePrefetching: UITableViewDataSourcePrefetching? = nil + public weak var fallbackDataSourcePrefetching: UITableViewDataSourcePrefetching? // MARK: Fallback delegate /// Fallback used when DataSource doesn't handle delegate method itself. /// - Note: The fallback delegate needs to be set *before* setting the table view's delegate, otherwise certain delegate methods will never be called. - public weak var fallbackDelegate: UITableViewDelegate? = nil + public weak var fallbackDelegate: UITableViewDelegate? public override func forwardingTarget(for aSelector: Selector!) -> Any? { return fallbackDelegate @@ -135,11 +137,13 @@ public class DataSource: NSObject { return cellDescriptors.values.contains(where: { ($0 as? CellDescriptorTypeiOS11)?.trailingSwipeActionsClosure != nil }) } + // MARK: ContextMenu + // MARK: Additional - public var isRowHidden: ((RowType, IndexPath) -> Bool)? = nil - public var isSectionHidden: ((SectionType, Int) -> Bool)? = nil - public var update: ((RowType, UITableViewCell, IndexPath) -> Void)? = nil + public var isRowHidden: ((RowType, IndexPath) -> Bool)? + public var isSectionHidden: ((SectionType, Int) -> Bool)? + public var update: ((RowType, UITableViewCell, IndexPath) -> Void)? // MARK: Internal @@ -159,15 +163,15 @@ public class DataSource: NSObject { self.cellDescriptors[d.rowIdentifier] = d } - self.addDescriptorIfNotSet(SeparatorLineCell.descriptorLine) - self.addDescriptorIfNotSet(SeparatorLineCell.descriptorCustomView) + addDescriptorIfNotSet(SeparatorLineCell.descriptorLine) + addDescriptorIfNotSet(SeparatorLineCell.descriptorCustomView) let defaultSectionDescriptors: [SectionDescriptorType] = [ SectionDescriptor(), SectionDescriptor() - .header { (title, _) in + .header { title, _ in .title(title) - } + } ] for d in defaultSectionDescriptors { @@ -180,8 +184,8 @@ public class DataSource: NSObject { } private func addDescriptorIfNotSet(_ descriptor: CellDescriptorType) { - if self.cellDescriptors[descriptor.rowIdentifier] == nil { - self.cellDescriptors[descriptor.rowIdentifier] = descriptor + if cellDescriptors[descriptor.rowIdentifier] == nil { + cellDescriptors[descriptor.rowIdentifier] = descriptor } } @@ -244,7 +248,7 @@ public class DataSource: NSObject { return nil } } - + // MARK: Visibility internal func updateVisibility() { @@ -266,7 +270,7 @@ public class DataSource: NSObject { isHidden = false } - if isHidden == false && section.numberOfVisibleRows > 0 { + if isHidden == false, section.numberOfVisibleRows > 0 { visibleSections.append(section) } } @@ -300,8 +304,7 @@ public class DataSource: NSObject { rowReloadAnimation: UITableView.RowAnimation = .none, sectionDeletionAnimation: UITableView.RowAnimation = .fade, sectionInsertionAnimation: UITableView.RowAnimation = .fade - ) { - + ) { let oldSections = visibleSections.map { $0.diffableSection } let newSections = updateSectionVisiblity() let diffableNewSections = newSections.map { $0.diffableSection } @@ -309,7 +312,7 @@ public class DataSource: NSObject { let diff = computeDiff(oldSections: oldSections, newSections: diffableNewSections) let updates = computeUpdate(oldSections: oldSections, newSections: diffableNewSections) - self.visibleSections = newSections + visibleSections = newSections if rowReloadAnimation == .none { for update in updates { @@ -323,7 +326,8 @@ public class DataSource: NSObject { rowInsertionAnimation: rowInsertionAnimation, rowReloadAnimation: rowReloadAnimation, sectionDeletionAnimation: sectionDeletionAnimation, - sectionInsertionAnimation: sectionInsertionAnimation) + sectionInsertionAnimation: sectionInsertionAnimation + ) } public func updateRow(_ tableView: UITableView, row: RowType, at indexPath: IndexPath) { @@ -331,9 +335,9 @@ public class DataSource: NSObject { let closure = cellDescriptor.updateClosure - ?? update - ?? cellDescriptor.configureClosure - ?? configure + ?? update + ?? cellDescriptor.configureClosure + ?? configure if let cell = tableView.cellForRow(at: indexPath), let closure = closure { closure(row, cell, indexPath) @@ -349,8 +353,8 @@ extension DataSource { return nil } - return { [weak self] (rowType, indexPath) in - return self?._leadingSwipeActions?(rowType, indexPath) as? UISwipeActionsConfiguration + return { [weak self] rowType, indexPath in + self?._leadingSwipeActions?(rowType, indexPath) as? UISwipeActionsConfiguration } } set { @@ -364,14 +368,31 @@ extension DataSource { return nil } - return { [weak self] (rowType, indexPath) in - return self?._trailingSwipeActions?(rowType, indexPath) as? UISwipeActionsConfiguration + return { [weak self] rowType, indexPath in + self?._trailingSwipeActions?(rowType, indexPath) as? UISwipeActionsConfiguration } } set { _trailingSwipeActions = newValue } } - } +@available(iOS 13,*) +extension DataSource { + public var configurationForMenuAtLocationClosure: ((RowType, IndexPath) -> UIContextMenuConfiguration?)? { + get { + if _configurationForMenuAtLocationClosure == nil { + return nil + } + + return { [weak self] rowType, indexPath in + self?._configurationForMenuAtLocationClosure?(rowType, indexPath) as? UIContextMenuConfiguration + } + } + + set { + _configurationForMenuAtLocationClosure = newValue + } + } +} diff --git a/Example/ViewControllers/Examples/DiffViewController.swift b/Example/ViewControllers/Examples/DiffViewController.swift index 914aced..6407b12 100644 --- a/Example/ViewControllers/Examples/DiffViewController.swift +++ b/Example/ViewControllers/Examples/DiffViewController.swift @@ -6,26 +6,56 @@ // Copyright © 2017 aaa - all about apps GmbH. All rights reserved. // -import UIKit import DataSource +import UIKit // MARK: - View Controller class DiffViewController: UITableViewController { - var counter = 0 lazy var dataSource: DataSource = { - DataSource( - cellDescriptors: [ - CellDescriptor() - .configure { (item, cell, indexPath) in - cell.textLabel?.text = item.text - } - .update { (item, cell, indexPath) in - cell.textLabel?.update(text: item.text, animated: true) - } - ]) + if #available(iOS 13.0, *) { + return DataSource( + cellDescriptors: [ + CellDescriptor() + .configure { item, cell, _ in + cell.textLabel?.text = item.text + } + .update { item, cell, _ in + cell.textLabel?.update(text: item.text, animated: true) + } + .configurationForMenuAtLocation { _, indexPath -> UIContextMenuConfiguration in + let index = indexPath.row + + let identifier = "\(index)" as NSString + return UIContextMenuConfiguration(identifier: identifier, previewProvider: nil) { _ in + let mapAction = UIAction( + title: "View map", + image: UIImage(systemName: "map")) { _ in + } + + let shareAction = UIAction( + title: "Share", + image: UIImage(systemName: "square.and.arrow.up")) { _ in + } + + return UIMenu(title: "", image: nil, children: [mapAction, shareAction]) + } + } + ]) + } else { + return DataSource( + cellDescriptors: [ + CellDescriptor() + .configure { item, cell, _ in + cell.textLabel?.text = item.text + } + .update { item, cell, _ in + cell.textLabel?.update(text: item.text, animated: true) + } + ]) + } }() override func viewDidLoad() { @@ -56,22 +86,21 @@ class DiffViewController: UITableViewController { }) ] } - + @IBAction func refresh(_ sender: Any) { counter += 1 dataSource.sections = createSections() dataSource.reloadDataAnimated(tableView, - rowDeletionAnimation: .automatic, - rowInsertionAnimation: .automatic, - rowReloadAnimation: .none) + rowDeletionAnimation: .automatic, + rowInsertionAnimation: .automatic, + rowReloadAnimation: .none) } } // MARK: - Diff Item struct DiffItem: Hashable { - let value: Int let text: String @@ -85,4 +114,4 @@ struct DiffItem: Hashable { } } -extension DiffItem: Diffable { } +extension DiffItem: Diffable {} From dc08a151d37e9f7b5e67fda6e2768b15a8cca3c4 Mon Sep 17 00:00:00 2001 From: Sandin Date: Wed, 9 Sep 2020 16:49:53 +0200 Subject: [PATCH 3/4] create seperate example for the context menu and clean diff example --- DataSource.xcodeproj/project.pbxproj | 4 ++ .../Storyboards/Base.lproj/Main.storyboard | 28 ++++++-- .../ContextMenuViewController.swift | 67 +++++++++++++++++++ .../Examples/DiffViewController.swift | 51 +++----------- .../ViewControllers/StartViewController.swift | 1 + 5 files changed, 106 insertions(+), 45 deletions(-) create mode 100644 Example/ViewControllers/ContextMenuViewController.swift diff --git a/DataSource.xcodeproj/project.pbxproj b/DataSource.xcodeproj/project.pbxproj index ab73915..657dcd5 100644 --- a/DataSource.xcodeproj/project.pbxproj +++ b/DataSource.xcodeproj/project.pbxproj @@ -51,6 +51,7 @@ 4C6076DF21490C80002E8BD1 /* SeparatedSectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C6076DE21490C80002E8BD1 /* SeparatedSectionViewController.swift */; }; 4CA65F60214F952E004F2F19 /* UIView+AutoLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CA65F5F214F952E004F2F19 /* UIView+AutoLayout.swift */; }; 5C61C91820AF0AB0003A08B8 /* SwipeActionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C61C91720AF0AB0003A08B8 /* SwipeActionViewController.swift */; }; + 5F91D0C625091B8300CF5053 /* ContextMenuViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F91D0C525091B8300CF5053 /* ContextMenuViewController.swift */; }; 5FD722022500F36800835AA1 /* Differ in Frameworks */ = {isa = PBXBuildFile; productRef = 5FD722012500F36800835AA1 /* Differ */; }; D8D61BEE21E4DD3E00937D1C /* SeparatorLineViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8D61BED21E4DD3E00937D1C /* SeparatorLineViewModel.swift */; }; D8D61BF021E4E11300937D1C /* SeparatorCustomViewViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8D61BEF21E4E11300937D1C /* SeparatorCustomViewViewModel.swift */; }; @@ -154,6 +155,7 @@ 4C6076DE21490C80002E8BD1 /* SeparatedSectionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeparatedSectionViewController.swift; sourceTree = ""; }; 4CA65F5F214F952E004F2F19 /* UIView+AutoLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+AutoLayout.swift"; sourceTree = ""; }; 5C61C91720AF0AB0003A08B8 /* SwipeActionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwipeActionViewController.swift; sourceTree = ""; }; + 5F91D0C525091B8300CF5053 /* ContextMenuViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContextMenuViewController.swift; sourceTree = ""; }; D8D61BED21E4DD3E00937D1C /* SeparatorLineViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeparatorLineViewModel.swift; sourceTree = ""; }; D8D61BEF21E4E11300937D1C /* SeparatorCustomViewViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeparatorCustomViewViewModel.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -255,6 +257,7 @@ 5C61C91720AF0AB0003A08B8 /* SwipeActionViewController.swift */, 4C6076DE21490C80002E8BD1 /* SeparatedSectionViewController.swift */, 3903C1822428C7410094EF50 /* ExpandableCellViewController.swift */, + 5F91D0C525091B8300CF5053 /* ContextMenuViewController.swift */, ); name = Examples; sourceTree = ""; @@ -507,6 +510,7 @@ 3903C1852428C7DE0094EF50 /* TextCell.swift in Sources */, 396E02E020A1B0090072291F /* SwipeToDeleteViewController.swift in Sources */, 3968B9161E7C261600EE876F /* UILabel+Animation.swift in Sources */, + 5F91D0C625091B8300CF5053 /* ContextMenuViewController.swift in Sources */, 39E9E3AE1E659D7D00A3C300 /* SwitchCell.swift in Sources */, 3903C1832428C7410094EF50 /* ExpandableCellViewController.swift in Sources */, 39E9E3A91E6566AD00A3C300 /* TitleCell.swift in Sources */, diff --git a/Example/Storyboards/Base.lproj/Main.storyboard b/Example/Storyboards/Base.lproj/Main.storyboard index 69eed35..4944c47 100644 --- a/Example/Storyboards/Base.lproj/Main.storyboard +++ b/Example/Storyboards/Base.lproj/Main.storyboard @@ -1,9 +1,9 @@ - + - + @@ -48,6 +48,7 @@ + @@ -215,7 +216,7 @@ - + @@ -360,7 +361,26 @@ - + + + + + + + + + + + + + + + + + + + + diff --git a/Example/ViewControllers/ContextMenuViewController.swift b/Example/ViewControllers/ContextMenuViewController.swift new file mode 100644 index 0000000..7a84cb5 --- /dev/null +++ b/Example/ViewControllers/ContextMenuViewController.swift @@ -0,0 +1,67 @@ +// +// ContextMenuViewController.swift +// Example +// +// Created by Sandin Dulić on 09.09.20. +// Copyright © 2020 aaa - all about apps GmbH. All rights reserved. +// + +import UIKit +import DataSource + +@available(iOS 13.0, *) +class ContextMenuViewController: UITableViewController { + lazy var dataSource: DataSource = { + DataSource( + cellDescriptors: [ + CellDescriptor() + .configure { item, cell, _ in + cell.textLabel?.text = item + } + .configurationForMenuAtLocation { [weak self] _, indexPath -> UIContextMenuConfiguration in + guard let self = self else { return UIContextMenuConfiguration() } + let index = indexPath.row + + let identifier = "\(index)" as NSString + return self.createContextMenuConfiguration(with: identifier) + } + ]) + }() + + override func viewDidLoad() { + super.viewDidLoad() + + title = "Context menu example" + + tableView.dataSource = dataSource + tableView.delegate = dataSource + + dataSource.sections = createSections() + dataSource.reloadData(tableView, animated: false) + } + + func createSections() -> [Section] { + let english = ["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten"] + + + return [ + Section(items: english) + ] + } + + private func createContextMenuConfiguration(with identifier: NSString) -> UIContextMenuConfiguration { + UIContextMenuConfiguration(identifier: identifier, previewProvider: nil) { _ in + let mapAction = UIAction( + title: "Some title", + image: UIImage(systemName: "map")) { _ in + } + + let shareAction = UIAction( + title: "Some title 2", + image: UIImage(systemName: "square.and.arrow.up")) { _ in + } + + return UIMenu(title: "", image: nil, children: [mapAction, shareAction]) + } + } +} diff --git a/Example/ViewControllers/Examples/DiffViewController.swift b/Example/ViewControllers/Examples/DiffViewController.swift index 6407b12..819a05b 100644 --- a/Example/ViewControllers/Examples/DiffViewController.swift +++ b/Example/ViewControllers/Examples/DiffViewController.swift @@ -15,47 +15,16 @@ class DiffViewController: UITableViewController { var counter = 0 lazy var dataSource: DataSource = { - if #available(iOS 13.0, *) { - return DataSource( - cellDescriptors: [ - CellDescriptor() - .configure { item, cell, _ in - cell.textLabel?.text = item.text - } - .update { item, cell, _ in - cell.textLabel?.update(text: item.text, animated: true) - } - .configurationForMenuAtLocation { _, indexPath -> UIContextMenuConfiguration in - let index = indexPath.row - - let identifier = "\(index)" as NSString - return UIContextMenuConfiguration(identifier: identifier, previewProvider: nil) { _ in - let mapAction = UIAction( - title: "View map", - image: UIImage(systemName: "map")) { _ in - } - - let shareAction = UIAction( - title: "Share", - image: UIImage(systemName: "square.and.arrow.up")) { _ in - } - - return UIMenu(title: "", image: nil, children: [mapAction, shareAction]) - } - } - ]) - } else { - return DataSource( - cellDescriptors: [ - CellDescriptor() - .configure { item, cell, _ in - cell.textLabel?.text = item.text - } - .update { item, cell, _ in - cell.textLabel?.update(text: item.text, animated: true) - } - ]) - } + DataSource( + cellDescriptors: [ + CellDescriptor() + .configure { item, cell, _ in + cell.textLabel?.text = item.text + } + .update { item, cell, _ in + cell.textLabel?.update(text: item.text, animated: true) + } + ]) }() override func viewDidLoad() { diff --git a/Example/ViewControllers/StartViewController.swift b/Example/ViewControllers/StartViewController.swift index 2950738..ea37b48 100644 --- a/Example/ViewControllers/StartViewController.swift +++ b/Example/ViewControllers/StartViewController.swift @@ -41,6 +41,7 @@ class StartViewController: UITableViewController { Example(title: "Swipe To Delete", segue: "showSwipeToDelete"), Example(title: "Custom separators", segue: "showSeparatedSection"), Example(title: "Expandable Cell", segue: "showExpandableCell"), + Example(title: "Context Menu", segue: "showContextMenuExample") ] let separatorItems = [ From 8a892902bf807efc7c5b5b58b902f298224870f0 Mon Sep 17 00:00:00 2001 From: Sandin Date: Thu, 10 Sep 2020 08:05:21 +0200 Subject: [PATCH 4/4] renaming --- Example/ViewControllers/ContextMenuViewController.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Example/ViewControllers/ContextMenuViewController.swift b/Example/ViewControllers/ContextMenuViewController.swift index 7a84cb5..c4b23bc 100644 --- a/Example/ViewControllers/ContextMenuViewController.swift +++ b/Example/ViewControllers/ContextMenuViewController.swift @@ -41,11 +41,11 @@ class ContextMenuViewController: UITableViewController { } func createSections() -> [Section] { - let english = ["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten"] + let items = ["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten"] return [ - Section(items: english) + Section(items: items) ] }