From 2bd4f1738bffa960d14e7429f451daebaafb6625 Mon Sep 17 00:00:00 2001 From: carefree <946715806@qq.com> Date: Tue, 11 Oct 2022 15:16:10 +0800 Subject: [PATCH] upgrade version --- EasyListView.podspec | 4 +- EasyListViewExample.xcodeproj/project.pbxproj | 128 +-- .../contents.xcworkspacedata | 10 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + EasyListViewExample/AppDelegate.swift | 6 + .../Demo1/FormListController.swift | 29 +- .../Demo2/UserListController.swift | 5 +- .../Main/MainViewController.swift | 5 +- EasyListViewExample/Main/ObjCTestController.m | 3 +- .../Animator/ESRefreshHeaderAnimator.swift | 2 +- Podfile | 7 + Podfile.lock | 23 + Pods/EasyCompatible/LICENSE | 21 + Pods/EasyCompatible/README.md | 2 + .../Sources/EasyCompatible.swift | 35 + Pods/Local Podspecs/EasyListView.podspec.json | 26 + Pods/Manifest.lock | 23 + Pods/Pods.xcodeproj/project.pbxproj | 892 ++++++++++++++++++ .../EasyCompatible/EasyCompatible-Info.plist | 26 + .../EasyCompatible/EasyCompatible-dummy.m | 5 + .../EasyCompatible/EasyCompatible-prefix.pch | 12 + .../EasyCompatible/EasyCompatible-umbrella.h | 16 + .../EasyCompatible.debug.xcconfig | 13 + .../EasyCompatible/EasyCompatible.modulemap | 6 + .../EasyCompatible.release.xcconfig | 13 + .../EasyListView/EasyListView-Info.plist | 26 + .../EasyListView/EasyListView-dummy.m | 5 + .../EasyListView/EasyListView-prefix.pch | 12 + .../EasyListView/EasyListView-umbrella.h | 16 + .../EasyListView/EasyListView.debug.xcconfig | 15 + .../EasyListView/EasyListView.modulemap | 6 + .../EasyListView.release.xcconfig | 15 + .../Pods-EasyListViewExample-Info.plist | 26 + ...yListViewExample-acknowledgements.markdown | 53 ++ ...EasyListViewExample-acknowledgements.plist | 91 ++ .../Pods-EasyListViewExample-dummy.m | 5 + ...le-frameworks-Debug-input-files.xcfilelist | 3 + ...e-frameworks-Debug-output-files.xcfilelist | 2 + ...-frameworks-Release-input-files.xcfilelist | 3 + ...frameworks-Release-output-files.xcfilelist | 2 + .../Pods-EasyListViewExample-frameworks.sh | 188 ++++ .../Pods-EasyListViewExample-umbrella.h | 16 + .../Pods-EasyListViewExample.debug.xcconfig | 15 + .../Pods-EasyListViewExample.modulemap | 6 + .../Pods-EasyListViewExample.release.xcconfig | 15 + README.md | 364 +++++-- Sources/EasyListExtension.swift | 823 ---------------- Sources/EasyListObjC.swift | 176 ---- Sources/ObjC/EasyListObjC.swift | 298 ++++++ Sources/ObjC/EasyListObjCDeprecated.swift | 115 +++ Sources/Swift/EasyListAppend.swift | 105 +++ Sources/Swift/EasyListAppendDeprecated.swift | 114 +++ Sources/Swift/EasyListAttributes.swift | 86 ++ Sources/{ => Swift}/EasyListConstraint.swift | 0 Sources/{ => Swift}/EasyListCoordinator.swift | 22 +- Sources/Swift/EasyListDelete.swift | 63 ++ Sources/Swift/EasyListDeleteDeprecated.swift | 51 + Sources/Swift/EasyListDisposable.swift | 124 +++ Sources/Swift/EasyListExtension.swift | 332 +++++++ Sources/Swift/EasyListInsert.swift | 243 +++++ Sources/Swift/EasyListInsertDeprecated.swift | 223 +++++ Sources/{ => Swift}/EasyListView.swift | 0 62 files changed, 3796 insertions(+), 1183 deletions(-) create mode 100644 EasyListViewExample.xcworkspace/contents.xcworkspacedata create mode 100644 EasyListViewExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 Podfile create mode 100644 Podfile.lock create mode 100644 Pods/EasyCompatible/LICENSE create mode 100644 Pods/EasyCompatible/README.md create mode 100644 Pods/EasyCompatible/Sources/EasyCompatible.swift create mode 100644 Pods/Local Podspecs/EasyListView.podspec.json create mode 100644 Pods/Manifest.lock create mode 100644 Pods/Pods.xcodeproj/project.pbxproj create mode 100644 Pods/Target Support Files/EasyCompatible/EasyCompatible-Info.plist create mode 100644 Pods/Target Support Files/EasyCompatible/EasyCompatible-dummy.m create mode 100644 Pods/Target Support Files/EasyCompatible/EasyCompatible-prefix.pch create mode 100644 Pods/Target Support Files/EasyCompatible/EasyCompatible-umbrella.h create mode 100644 Pods/Target Support Files/EasyCompatible/EasyCompatible.debug.xcconfig create mode 100644 Pods/Target Support Files/EasyCompatible/EasyCompatible.modulemap create mode 100644 Pods/Target Support Files/EasyCompatible/EasyCompatible.release.xcconfig create mode 100644 Pods/Target Support Files/EasyListView/EasyListView-Info.plist create mode 100644 Pods/Target Support Files/EasyListView/EasyListView-dummy.m create mode 100644 Pods/Target Support Files/EasyListView/EasyListView-prefix.pch create mode 100644 Pods/Target Support Files/EasyListView/EasyListView-umbrella.h create mode 100644 Pods/Target Support Files/EasyListView/EasyListView.debug.xcconfig create mode 100644 Pods/Target Support Files/EasyListView/EasyListView.modulemap create mode 100644 Pods/Target Support Files/EasyListView/EasyListView.release.xcconfig create mode 100644 Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-Info.plist create mode 100644 Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-acknowledgements.markdown create mode 100644 Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-acknowledgements.plist create mode 100644 Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-dummy.m create mode 100644 Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-frameworks-Debug-input-files.xcfilelist create mode 100644 Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-frameworks-Debug-output-files.xcfilelist create mode 100644 Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-frameworks-Release-input-files.xcfilelist create mode 100644 Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-frameworks-Release-output-files.xcfilelist create mode 100755 Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-frameworks.sh create mode 100644 Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-umbrella.h create mode 100644 Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample.debug.xcconfig create mode 100644 Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample.modulemap create mode 100644 Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample.release.xcconfig delete mode 100644 Sources/EasyListExtension.swift delete mode 100644 Sources/EasyListObjC.swift create mode 100644 Sources/ObjC/EasyListObjC.swift create mode 100644 Sources/ObjC/EasyListObjCDeprecated.swift create mode 100644 Sources/Swift/EasyListAppend.swift create mode 100644 Sources/Swift/EasyListAppendDeprecated.swift create mode 100644 Sources/Swift/EasyListAttributes.swift rename Sources/{ => Swift}/EasyListConstraint.swift (100%) rename Sources/{ => Swift}/EasyListCoordinator.swift (75%) create mode 100644 Sources/Swift/EasyListDelete.swift create mode 100644 Sources/Swift/EasyListDeleteDeprecated.swift create mode 100644 Sources/Swift/EasyListDisposable.swift create mode 100644 Sources/Swift/EasyListExtension.swift create mode 100644 Sources/Swift/EasyListInsert.swift create mode 100644 Sources/Swift/EasyListInsertDeprecated.swift rename Sources/{ => Swift}/EasyListView.swift (100%) diff --git a/EasyListView.podspec b/EasyListView.podspec index abb33eb..92e5304 100644 --- a/EasyListView.podspec +++ b/EasyListView.podspec @@ -1,15 +1,15 @@ Pod::Spec.new do |s| s.name = "EasyListView" - s.version = "1.2.4" + s.version = "1.3.0" s.summary = "快速搭建静态及可重用列表" s.homepage = "https://github.com/moliya/EasyListView" s.license = "MIT" s.author = {'Carefree' => '946715806@qq.com'} s.source = { :git => "https://github.com/moliya/EasyListView.git", :tag => s.version} - s.source_files = "Sources/*" s.requires_arc = true s.platform = :ios, '9.0' s.swift_version = '5.0' s.dependency 'EasyCompatible' + s.source_files = "Sources/**/*" end diff --git a/EasyListViewExample.xcodeproj/project.pbxproj b/EasyListViewExample.xcodeproj/project.pbxproj index ddfd0a4..642258c 100644 --- a/EasyListViewExample.xcodeproj/project.pbxproj +++ b/EasyListViewExample.xcodeproj/project.pbxproj @@ -3,19 +3,14 @@ archiveVersion = 1; classes = { }; - objectVersion = 52; + objectVersion = 50; objects = { /* Begin PBXBuildFile section */ - 17164BD627EDB6950007A2A0 /* EasyCompatible in Frameworks */ = {isa = PBXBuildFile; productRef = 17164BD527EDB6950007A2A0 /* EasyCompatible */; }; 171D6E9E24922D0E001FF205 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 171D6E9D24922D0E001FF205 /* AppDelegate.swift */; }; 171D6EA524922D0E001FF205 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 171D6EA324922D0E001FF205 /* Main.storyboard */; }; 171D6EA724922D12001FF205 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 171D6EA624922D12001FF205 /* Assets.xcassets */; }; 171D6EAA24922D12001FF205 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 171D6EA824922D12001FF205 /* LaunchScreen.storyboard */; }; - 171D6EB724922EAF001FF205 /* EasyListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 171D6EB624922EAF001FF205 /* EasyListView.swift */; }; - 176D9E8624DE728A004972E9 /* EasyListCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 176D9E8524DE728A004972E9 /* EasyListCoordinator.swift */; }; - 176D9E8824DE731C004972E9 /* EasyListExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 176D9E8724DE731C004972E9 /* EasyListExtension.swift */; }; - 177AFA9F24DC2216004A9E92 /* EasyListConstraint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 177AFA9E24DC2215004A9E92 /* EasyListConstraint.swift */; }; 1782C95724EA2BF9008FE4CC /* MainViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1782C95624EA2BF9008FE4CC /* MainViewController.swift */; }; 1782C96024EA56C8008FE4CC /* EasyListCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1782C95F24EA56C8008FE4CC /* EasyListCell.swift */; }; 1782C96224EA6335008FE4CC /* FormListController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1782C96124EA6335008FE4CC /* FormListController.swift */; }; @@ -50,8 +45,8 @@ 1782C9AC24EB779D008FE4CC /* ESPullToRefresh+Manager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1782C9A224EB779C008FE4CC /* ESPullToRefresh+Manager.swift */; }; 1782C9AD24EB779D008FE4CC /* ESRefreshAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1782C9A324EB779C008FE4CC /* ESRefreshAnimator.swift */; }; 1782C9AE24EB779D008FE4CC /* ESRefreshComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1782C9A424EB779D008FE4CC /* ESRefreshComponent.swift */; }; - 1782C9B024EBA9BB008FE4CC /* EasyListObjC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1782C9AF24EBA9BB008FE4CC /* EasyListObjC.swift */; }; 1782C9B324EBB0BB008FE4CC /* ObjCTestController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1782C9B224EBB0BB008FE4CC /* ObjCTestController.m */; }; + 7377F0024980E316A2D3F686 /* Pods_EasyListViewExample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A819D9BD340487735560486 /* Pods_EasyListViewExample.framework */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -61,11 +56,7 @@ 171D6EA624922D12001FF205 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 171D6EA924922D12001FF205 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 171D6EAB24922D12001FF205 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 171D6EB624922EAF001FF205 /* EasyListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = EasyListView.swift; path = Sources/EasyListView.swift; sourceTree = SOURCE_ROOT; }; - 176D9E8524DE728A004972E9 /* EasyListCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = EasyListCoordinator.swift; path = Sources/EasyListCoordinator.swift; sourceTree = SOURCE_ROOT; }; - 176D9E8724DE731C004972E9 /* EasyListExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = EasyListExtension.swift; path = Sources/EasyListExtension.swift; sourceTree = SOURCE_ROOT; }; 176D9E8924DE86A8004972E9 /* EasyListViewExample-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "EasyListViewExample-Bridging-Header.h"; sourceTree = ""; }; - 177AFA9E24DC2215004A9E92 /* EasyListConstraint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = EasyListConstraint.swift; path = Sources/EasyListConstraint.swift; sourceTree = SOURCE_ROOT; }; 1782C95624EA2BF9008FE4CC /* MainViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainViewController.swift; sourceTree = ""; }; 1782C95F24EA56C8008FE4CC /* EasyListCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EasyListCell.swift; sourceTree = ""; }; 1782C96124EA6335008FE4CC /* FormListController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormListController.swift; sourceTree = ""; }; @@ -102,9 +93,11 @@ 1782C9A224EB779C008FE4CC /* ESPullToRefresh+Manager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ESPullToRefresh+Manager.swift"; sourceTree = ""; }; 1782C9A324EB779C008FE4CC /* ESRefreshAnimator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ESRefreshAnimator.swift; sourceTree = ""; }; 1782C9A424EB779D008FE4CC /* ESRefreshComponent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ESRefreshComponent.swift; sourceTree = ""; }; - 1782C9AF24EBA9BB008FE4CC /* EasyListObjC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = EasyListObjC.swift; path = Sources/EasyListObjC.swift; sourceTree = SOURCE_ROOT; }; 1782C9B124EBB0BB008FE4CC /* ObjCTestController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ObjCTestController.h; sourceTree = ""; }; 1782C9B224EBB0BB008FE4CC /* ObjCTestController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ObjCTestController.m; sourceTree = ""; }; + 2A819D9BD340487735560486 /* Pods_EasyListViewExample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_EasyListViewExample.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 2D7887A13346B92916E9F38C /* Pods-EasyListViewExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-EasyListViewExample.release.xcconfig"; path = "Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample.release.xcconfig"; sourceTree = ""; }; + 75C361A72832AA3274877450 /* Pods-EasyListViewExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-EasyListViewExample.debug.xcconfig"; path = "Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -112,7 +105,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 17164BD627EDB6950007A2A0 /* EasyCompatible in Frameworks */, + 7377F0024980E316A2D3F686 /* Pods_EasyListViewExample.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -124,6 +117,8 @@ children = ( 171D6E9C24922D0E001FF205 /* EasyListViewExample */, 171D6E9B24922D0E001FF205 /* Products */, + 8CA7CD663B621E5C9B20A29D /* Pods */, + ABDF0276DF1052BB1F8CECDA /* Frameworks */, ); sourceTree = ""; }; @@ -138,7 +133,6 @@ 171D6E9C24922D0E001FF205 /* EasyListViewExample */ = { isa = PBXGroup; children = ( - 171D6EB224922E5C001FF205 /* Sources */, 1782C95524EA29FA008FE4CC /* Main */, 1782C95824EA2CE3008FE4CC /* Demo1 */, 1782C96324EA6AE9008FE4CC /* Demo2 */, @@ -153,18 +147,6 @@ path = EasyListViewExample; sourceTree = ""; }; - 171D6EB224922E5C001FF205 /* Sources */ = { - isa = PBXGroup; - children = ( - 171D6EB624922EAF001FF205 /* EasyListView.swift */, - 176D9E8524DE728A004972E9 /* EasyListCoordinator.swift */, - 177AFA9E24DC2215004A9E92 /* EasyListConstraint.swift */, - 176D9E8724DE731C004972E9 /* EasyListExtension.swift */, - 1782C9AF24EBA9BB008FE4CC /* EasyListObjC.swift */, - ); - name = Sources; - sourceTree = ""; - }; 1782C95524EA29FA008FE4CC /* Main */ = { isa = PBXGroup; children = ( @@ -253,6 +235,24 @@ path = Animator; sourceTree = ""; }; + 8CA7CD663B621E5C9B20A29D /* Pods */ = { + isa = PBXGroup; + children = ( + 75C361A72832AA3274877450 /* Pods-EasyListViewExample.debug.xcconfig */, + 2D7887A13346B92916E9F38C /* Pods-EasyListViewExample.release.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; + ABDF0276DF1052BB1F8CECDA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 2A819D9BD340487735560486 /* Pods_EasyListViewExample.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -260,18 +260,17 @@ isa = PBXNativeTarget; buildConfigurationList = 171D6EAE24922D12001FF205 /* Build configuration list for PBXNativeTarget "EasyListViewExample" */; buildPhases = ( + A99264109D60D80689605202 /* [CP] Check Pods Manifest.lock */, 171D6E9624922D0E001FF205 /* Sources */, 171D6E9724922D0E001FF205 /* Frameworks */, 171D6E9824922D0E001FF205 /* Resources */, + 9C2933B5F86CA194B3A787F7 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); dependencies = ( ); name = EasyListViewExample; - packageProductDependencies = ( - 17164BD527EDB6950007A2A0 /* EasyCompatible */, - ); productName = EasyListViewExample; productReference = 171D6E9A24922D0E001FF205 /* EasyListViewExample.app */; productType = "com.apple.product-type.application"; @@ -303,9 +302,6 @@ "zh-Hant", ); mainGroup = 171D6E9124922D0E001FF205; - packageReferences = ( - 17164BD427EDB6950007A2A0 /* XCRemoteSwiftPackageReference "EasyCompatible" */, - ); productRefGroup = 171D6E9B24922D0E001FF205 /* Products */; projectDirPath = ""; projectRoot = ""; @@ -330,6 +326,48 @@ }; /* End PBXResourcesBuildPhase section */ +/* Begin PBXShellScriptBuildPhase section */ + 9C2933B5F86CA194B3A787F7 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + A99264109D60D80689605202 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-EasyListViewExample-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + /* Begin PBXSourcesBuildPhase section */ 171D6E9624922D0E001FF205 /* Sources */ = { isa = PBXSourcesBuildPhase; @@ -340,11 +378,9 @@ 1782C98524EB7445008FE4CC /* Stevia+Center.swift in Sources */, 1782C95724EA2BF9008FE4CC /* MainViewController.swift in Sources */, 1782C98424EB7445008FE4CC /* Stevia+Operators.swift in Sources */, - 176D9E8824DE731C004972E9 /* EasyListExtension.swift in Sources */, 1782C9A924EB779D008FE4CC /* ESRefreshHeaderAnimator.swift in Sources */, 1782C98D24EB7445008FE4CC /* Stevia+Constraints.swift in Sources */, 1782C98624EB7445008FE4CC /* Stevia+Size.swift in Sources */, - 1782C9B024EBA9BB008FE4CC /* EasyListObjC.swift in Sources */, 1782C99524EB7445008FE4CC /* Stevia+Percentage.swift in Sources */, 1782C96224EA6335008FE4CC /* FormListController.swift in Sources */, 1782C98924EB7445008FE4CC /* Stevia+Baselines.swift in Sources */, @@ -355,7 +391,6 @@ 1782C99024EB7445008FE4CC /* Stevia+GetConstraint.swift in Sources */, 1782C9A524EB779D008FE4CC /* ESRefreshProtocol.swift in Sources */, 1782C98724EB7445008FE4CC /* Stevia+LayoutAnchors.swift in Sources */, - 177AFA9F24DC2216004A9E92 /* EasyListConstraint.swift in Sources */, 1782C98B24EB7445008FE4CC /* Stevia+Position.swift in Sources */, 1782C98F24EB7445008FE4CC /* Stevia+Hierarchy.swift in Sources */, 1782C98324EB7445008FE4CC /* Stevia+FlexibleMargin.swift in Sources */, @@ -364,14 +399,12 @@ 1782C9AD24EB779D008FE4CC /* ESRefreshAnimator.swift in Sources */, 1782C99324EB7445008FE4CC /* Stevia+DoubleDash.swift in Sources */, 171D6E9E24922D0E001FF205 /* AppDelegate.swift in Sources */, - 176D9E8624DE728A004972E9 /* EasyListCoordinator.swift in Sources */, 1782C9AB24EB779D008FE4CC /* ESRefreshFooterAnimator.swift in Sources */, 1782C9AC24EB779D008FE4CC /* ESPullToRefresh+Manager.swift in Sources */, 1782C9AE24EB779D008FE4CC /* ESRefreshComponent.swift in Sources */, 1782C96D24EAA90E008FE4CC /* UserCell.swift in Sources */, 1782C98C24EB7445008FE4CC /* Stevia+Fill.swift in Sources */, 1782C99224EB7445008FE4CC /* Stevia+Style.swift in Sources */, - 171D6EB724922EAF001FF205 /* EasyListView.swift in Sources */, 1782C98A24EB7445008FE4CC /* Stevia+Equation.swift in Sources */, 1782C9A724EB779D008FE4CC /* ES.swift in Sources */, ); @@ -525,6 +558,7 @@ }; 171D6EAF24922D12001FF205 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 75C361A72832AA3274877450 /* Pods-EasyListViewExample.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; @@ -546,6 +580,7 @@ }; 171D6EB024922D12001FF205 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 2D7887A13346B92916E9F38C /* Pods-EasyListViewExample.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; @@ -586,25 +621,6 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ - -/* Begin XCRemoteSwiftPackageReference section */ - 17164BD427EDB6950007A2A0 /* XCRemoteSwiftPackageReference "EasyCompatible" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "git@github.com:moliya/EasyCompatible.git"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 1.0.0; - }; - }; -/* End XCRemoteSwiftPackageReference section */ - -/* Begin XCSwiftPackageProductDependency section */ - 17164BD527EDB6950007A2A0 /* EasyCompatible */ = { - isa = XCSwiftPackageProductDependency; - package = 17164BD427EDB6950007A2A0 /* XCRemoteSwiftPackageReference "EasyCompatible" */; - productName = EasyCompatible; - }; -/* End XCSwiftPackageProductDependency section */ }; rootObject = 171D6E9224922D0E001FF205 /* Project object */; } diff --git a/EasyListViewExample.xcworkspace/contents.xcworkspacedata b/EasyListViewExample.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..c9eae4d --- /dev/null +++ b/EasyListViewExample.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/EasyListViewExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/EasyListViewExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/EasyListViewExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/EasyListViewExample/AppDelegate.swift b/EasyListViewExample/AppDelegate.swift index ebfe58b..5fed44e 100644 --- a/EasyListViewExample/AppDelegate.swift +++ b/EasyListViewExample/AppDelegate.swift @@ -15,6 +15,12 @@ class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. + if #available(iOS 13.0, *) { + let appearance = UINavigationBarAppearance() + appearance.configureWithOpaqueBackground() + UINavigationBar.appearance().scrollEdgeAppearance = appearance + UINavigationBar.appearance().standardAppearance = appearance + } return true } diff --git a/EasyListViewExample/Demo1/FormListController.swift b/EasyListViewExample/Demo1/FormListController.swift index 3130dfd..14d79b9 100644 --- a/EasyListViewExample/Demo1/FormListController.swift +++ b/EasyListViewExample/Demo1/FormListController.swift @@ -7,6 +7,7 @@ // import UIKit +import EasyListView class FormListController: UIViewController { @@ -37,17 +38,17 @@ class FormListController: UIViewController { view.backgroundColor = #colorLiteral(red: 0.8979505897, green: 0.8981012702, blue: 0.8979307413, alpha: 1) view.height(0.5) - self.scrollView.easy.append(view) + self.scrollView.easy.appendView(view) } - scrollView.easy.append({ + scrollView.easy.appendView { let label = UILabel() label.numberOfLines = 0 label.font = .systemFont(ofSize: 14) label.textColor = .lightGray label.text = "Section Title" return label - }(), with: UIEdgeInsets(top: 10, left: 16, bottom: 0, right: 16)) + }.insets(UIEdgeInsets(top: 10, left: 16, bottom: 0, right: 16)) let nameCell: UIView = { let cell = EasyListCell() @@ -70,7 +71,7 @@ class FormListController: UIViewController { return cell }() - scrollView.easy.append(nameCell, spacing: 10) + scrollView.easy.appendView(nameCell).spacing(10) addSeparator() @@ -94,7 +95,7 @@ class FormListController: UIViewController { return cell }() - scrollView.easy.append(emailCell) + scrollView.easy.appendView(emailCell) addSeparator() @@ -122,7 +123,7 @@ class FormListController: UIViewController { return cell }() - scrollView.easy.append(birthdayCell, for: "birthday", spacing: 0) + scrollView.easy.appendView(birthdayCell).identifier("birthday") addSeparator() @@ -141,16 +142,16 @@ class FormListController: UIViewController { return cell }() - scrollView.easy.append(switchCell) + scrollView.easy.appendView(switchCell) - scrollView.easy.append({ + scrollView.easy.appendView { let label = UILabel() label.numberOfLines = 0 label.font = .systemFont(ofSize: 16) label.textColor = .lightGray label.text = "1.AAA\n2.BBB\n3.CCC" return label - }(), with: UIEdgeInsets(top: 10, left: 16, bottom: 0, right: 16)) + }.insets(UIEdgeInsets(top: 10, left: 16, bottom: 0, right: 16)) let inputView: UIView = { let view = UIView() @@ -178,7 +179,7 @@ class FormListController: UIViewController { return view }() - scrollView.easy.append(inputView, spacing: 10) + scrollView.easy.appendView(inputView).spacing(10) let button = UIButton(type: .custom) button.setTitle("Done", for: .normal) @@ -187,7 +188,7 @@ class FormListController: UIViewController { button.clipsToBounds = true button.height(45) button.addTarget(self, action: #selector(tapDone), for: .touchUpInside) - scrollView.easy.append(button, with: UIEdgeInsets(top: 40, left: 16, bottom: 20, right: 16)) + scrollView.easy.appendView(button).insets(UIEdgeInsets(top: 40, left: 16, bottom: 20, right: 16)) } deinit { @@ -196,7 +197,7 @@ class FormListController: UIViewController { func tapBirthdayCell() { if let _ = scrollView.easy.getElement(identifier: "birthdaySelector") as? UIDatePicker { - scrollView.easy.delete("birthdaySelector") + scrollView.easy.deleteView("birthdaySelector") birthdayLabel.textColor = #colorLiteral(red: 0.4, green: 0.4, blue: 0.4, alpha: 1) return } @@ -216,7 +217,9 @@ class FormListController: UIViewController { } birthdayLabel.textColor = #colorLiteral(red: 0.9098039269, green: 0.4784313738, blue: 0.6431372762, alpha: 1) - scrollView.easy.insert(picker, after: "birthday", with: .zero, for: "birthdaySelector", completion: nil) + scrollView.easy.beginUpdates() + scrollView.easy.insertView(picker, after: "birthday").identifier("birthdaySelector") + scrollView.easy.endUpdates() } @objc func datePickerChanged(_ sender: UIDatePicker) { diff --git a/EasyListViewExample/Demo2/UserListController.swift b/EasyListViewExample/Demo2/UserListController.swift index 23d5186..25c2036 100644 --- a/EasyListViewExample/Demo2/UserListController.swift +++ b/EasyListViewExample/Demo2/UserListController.swift @@ -7,6 +7,7 @@ // import UIKit +import EasyListView class UserListController: UIViewController { @@ -71,7 +72,7 @@ class UserListController: UIViewController { return cell } - self.scrollView.easy.append(view) + self.scrollView.easy.appendView(view) } if self.scrollView.header?.isRefreshing == true { @@ -96,7 +97,7 @@ class UserListController: UIViewController { cell.set(name: self.users[index], avatar: UIImage(named: "avatar")) return cell } - self.scrollView.easy.append(view) + self.scrollView.easy.appendView(view) } self.scrollView.easy.endUpdates() diff --git a/EasyListViewExample/Main/MainViewController.swift b/EasyListViewExample/Main/MainViewController.swift index b2221a1..7389601 100644 --- a/EasyListViewExample/Main/MainViewController.swift +++ b/EasyListViewExample/Main/MainViewController.swift @@ -7,6 +7,7 @@ // import UIKit +import EasyListView class MainViewController: UIViewController { @@ -25,7 +26,7 @@ class MainViewController: UIViewController { return cell }() - scrollView.easy.append(cell1, spacing: 10) + scrollView.easy.appendView(cell1).spacing(10) let cell2: UIView = { let cell = EasyListCell() @@ -37,6 +38,6 @@ class MainViewController: UIViewController { return cell }() - scrollView.easy.append(cell2, spacing: 0.5) + scrollView.easy.appendView(cell2).spacing(0.5) } } diff --git a/EasyListViewExample/Main/ObjCTestController.m b/EasyListViewExample/Main/ObjCTestController.m index 3d5c244..0a0cf16 100644 --- a/EasyListViewExample/Main/ObjCTestController.m +++ b/EasyListViewExample/Main/ObjCTestController.m @@ -7,7 +7,7 @@ // #import "ObjCTestController.h" -#import "EasyListViewExample-Swift.h" +#import @interface ObjCTestController () @@ -21,6 +21,7 @@ - (void)viewDidLoad { EasyListView *listView = [[EasyListView alloc] init]; [listView easy_beginUpdates]; [listView easy_endUpdatesWithCompletion:nil]; + } @end diff --git a/EasyListViewExample/Vendor/ESPullToRefresh/Animator/ESRefreshHeaderAnimator.swift b/EasyListViewExample/Vendor/ESPullToRefresh/Animator/ESRefreshHeaderAnimator.swift index b756918..d706081 100644 --- a/EasyListViewExample/Vendor/ESPullToRefresh/Animator/ESRefreshHeaderAnimator.swift +++ b/EasyListViewExample/Vendor/ESPullToRefresh/Animator/ESRefreshHeaderAnimator.swift @@ -32,7 +32,7 @@ open class ESRefreshHeaderAnimator: UIView, ESRefreshProtocol, ESRefreshAnimator open var pullToRefreshDescription = NSLocalizedString("Pull to refresh", comment: "") { didSet { if pullToRefreshDescription != oldValue { - titleLabel.text = pullToRefreshDescription; + titleLabel.text = pullToRefreshDescription } } } diff --git a/Podfile b/Podfile new file mode 100644 index 0000000..7a2c695 --- /dev/null +++ b/Podfile @@ -0,0 +1,7 @@ +source 'https://cdn.cocoapods.org/' +use_frameworks! +platform :ios, '9.0' + +target 'EasyListViewExample' do + pod 'EasyListView', :path => './' +end diff --git a/Podfile.lock b/Podfile.lock new file mode 100644 index 0000000..e2e6201 --- /dev/null +++ b/Podfile.lock @@ -0,0 +1,23 @@ +PODS: + - EasyCompatible (1.0) + - EasyListView (1.3.0): + - EasyCompatible + +DEPENDENCIES: + - EasyListView (from `./`) + +SPEC REPOS: + trunk: + - EasyCompatible + +EXTERNAL SOURCES: + EasyListView: + :path: "./" + +SPEC CHECKSUMS: + EasyCompatible: 571e10cf69d018b820f65cd6b99f76573313db6e + EasyListView: ac1b3dcd19ef3fb5b2ea48b74b91a8171cc723e8 + +PODFILE CHECKSUM: 85d9c6237193f3c7e89929aa9b3c1282aad65d38 + +COCOAPODS: 1.11.3 diff --git a/Pods/EasyCompatible/LICENSE b/Pods/EasyCompatible/LICENSE new file mode 100644 index 0000000..7848fdd --- /dev/null +++ b/Pods/EasyCompatible/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 moliya + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Pods/EasyCompatible/README.md b/Pods/EasyCompatible/README.md new file mode 100644 index 0000000..9ca1330 --- /dev/null +++ b/Pods/EasyCompatible/README.md @@ -0,0 +1,2 @@ +# EasyCompatible +一个基础依赖 diff --git a/Pods/EasyCompatible/Sources/EasyCompatible.swift b/Pods/EasyCompatible/Sources/EasyCompatible.swift new file mode 100644 index 0000000..a100f77 --- /dev/null +++ b/Pods/EasyCompatible/Sources/EasyCompatible.swift @@ -0,0 +1,35 @@ +// +// EasyCompatible.swift +// EasyCompatible +// +// Created by carefree on 2022/3/25. +// Copyright © 2019 Carefree. All rights reserved. +// + +import Foundation + +// MARK: - 命名空间 +public struct EasyExtension { + public let base: Base + public init(_ base: Base) { + self.base = base + } +} + +public protocol EasyCompatible: AnyObject { } + +public protocol EasyCompatibleValue {} + +extension EasyCompatible { + public var easy: EasyExtension { + get { return EasyExtension(self) } + set { } + } +} + +extension EasyCompatibleValue { + public var easy: EasyExtension { + get { return EasyExtension(self) } + set { } + } +} diff --git a/Pods/Local Podspecs/EasyListView.podspec.json b/Pods/Local Podspecs/EasyListView.podspec.json new file mode 100644 index 0000000..cf772ee --- /dev/null +++ b/Pods/Local Podspecs/EasyListView.podspec.json @@ -0,0 +1,26 @@ +{ + "name": "EasyListView", + "version": "1.3.0", + "summary": "快速搭建静态及可重用列表", + "homepage": "https://github.com/moliya/EasyListView", + "license": "MIT", + "authors": { + "Carefree": "946715806@qq.com" + }, + "source": { + "git": "https://github.com/moliya/EasyListView.git", + "tag": "1.3.0" + }, + "requires_arc": true, + "platforms": { + "ios": "9.0" + }, + "swift_versions": "5.0", + "dependencies": { + "EasyCompatible": [ + + ] + }, + "source_files": "Sources/**/*", + "swift_version": "5.0" +} diff --git a/Pods/Manifest.lock b/Pods/Manifest.lock new file mode 100644 index 0000000..e2e6201 --- /dev/null +++ b/Pods/Manifest.lock @@ -0,0 +1,23 @@ +PODS: + - EasyCompatible (1.0) + - EasyListView (1.3.0): + - EasyCompatible + +DEPENDENCIES: + - EasyListView (from `./`) + +SPEC REPOS: + trunk: + - EasyCompatible + +EXTERNAL SOURCES: + EasyListView: + :path: "./" + +SPEC CHECKSUMS: + EasyCompatible: 571e10cf69d018b820f65cd6b99f76573313db6e + EasyListView: ac1b3dcd19ef3fb5b2ea48b74b91a8171cc723e8 + +PODFILE CHECKSUM: 85d9c6237193f3c7e89929aa9b3c1282aad65d38 + +COCOAPODS: 1.11.3 diff --git a/Pods/Pods.xcodeproj/project.pbxproj b/Pods/Pods.xcodeproj/project.pbxproj new file mode 100644 index 0000000..81d9614 --- /dev/null +++ b/Pods/Pods.xcodeproj/project.pbxproj @@ -0,0 +1,892 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 0FA2863A558AD78D8A97097AC9FCCAC3 /* EasyListAppendDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AB3E8D42751D63D16E5ACED4E82E0D2 /* EasyListAppendDeprecated.swift */; }; + 17411C6D28F42AAA00B5A062 /* EasyListDeleteDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17411C6C28F42AAA00B5A062 /* EasyListDeleteDeprecated.swift */; }; + 17ACACC0376B5CD47345C9B0011B26AE /* EasyListObjC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73147B023A28EFD1FC94F7BFCA66F465 /* EasyListObjC.swift */; }; + 397820FAF75252EEDA61C15837D2BD2F /* EasyCompatible-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = C60C75EC6F467D828687161D7DC55275 /* EasyCompatible-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4EF181BD4F9D36244719893D56EB9B6D /* EasyListAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = A849A0B4ADA2FBD77A8DE6BAAB3307CF /* EasyListAttributes.swift */; }; + 580C01C8B90466ED0BF5584957A8047E /* EasyListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E42FEFA8C924FB6935E427383154EF8 /* EasyListView.swift */; }; + 5A0802CA3EE27D194452AECAC40E9214 /* EasyListCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDFEAA6AC9D0AFDCFDC93DAC5CCCFBCC /* EasyListCoordinator.swift */; }; + 5C7C0F684425C19D4D7E86A1177DF6AD /* EasyCompatible.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA0430F87E305402EFAE2A8A4C9471A5 /* EasyCompatible.swift */; }; + 5E0EC6C11928235E98EA24947BE8C84B /* EasyListConstraint.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECB870EF5E6EB31B18943F0821F1A82F /* EasyListConstraint.swift */; }; + 5F767BF2F404002B2C4B2A0A75D8D6FA /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */; }; + 67E378D73F53EB5C4A8B9A29BC970F89 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */; }; + 8B6BAFB81AF489707F7DB5A2AA6F3051 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */; }; + A94A70751AF61E0AA739BA290110092A /* EasyListObjCDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 416EDBD62E0755546781C03B7860CDDF /* EasyListObjCDeprecated.swift */; }; + AA3C6828E485A58A93E52418D1915630 /* EasyListAppend.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E784486FB04AE932055287F32B01184 /* EasyListAppend.swift */; }; + B52AEFFD16A78EC2FF6684EA1312607E /* EasyListView-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = C095D3E321BB651072C68F4A5762CC60 /* EasyListView-dummy.m */; }; + C22F7FD6E05EC6895B2752A478F33E21 /* EasyListExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3B48F0641D9C60E1B10A84062AF2A55 /* EasyListExtension.swift */; }; + C9E4311192E54AB7354DB8100AB1B4F6 /* Pods-EasyListViewExample-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B264D2E22EF6B920AD175EEE6716631 /* Pods-EasyListViewExample-dummy.m */; }; + CE5BA9255696976AD15BB916DE6F9740 /* Pods-EasyListViewExample-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CF9FC8D859809A39070ADED10DF9BB9 /* Pods-EasyListViewExample-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D55F768A2B9A23627156126C949D5986 /* EasyListDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8661B95EB38CE735F557FFE16B13F011 /* EasyListDisposable.swift */; }; + DF97D4A0989DDA2470FD5F23859F9229 /* EasyListDelete.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B1795D2806A751242D819B67BC4B3BE /* EasyListDelete.swift */; }; + ED4E63541BDEB3C59330DBD18C108CA9 /* EasyCompatible-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F90D60DEFC96AE8426C64F336098A81 /* EasyCompatible-dummy.m */; }; + F130EA94A1683AA2912B59A66A0CD96E /* EasyListInsert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73CD48CD5DF5DC42B40934B4E929C0E0 /* EasyListInsert.swift */; }; + F4C04535A58E9EDF3D0481B4BE52E710 /* EasyListInsertDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = C81ADED5DEB7DD854E0D394493FE1E57 /* EasyListInsertDeprecated.swift */; }; + F9DE1A101BA450BD5D9A39A5D3A0ADCE /* EasyListView-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 99D14C850F6AF2956FE64C172356CBD6 /* EasyListView-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + B10B0FDC2AA0BD659771D029B566916D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 6D0949614762ADA89669D857188A9171; + remoteInfo = EasyCompatible; + }; + BCCAEBEA43A7A8C5B7C805698B715187 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 6D0949614762ADA89669D857188A9171; + remoteInfo = EasyCompatible; + }; + BEF977E3A8A2F8E12EE5C1B586D7FD04 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 158B7ADE69A453707A560D6EA60C90AF; + remoteInfo = EasyListView; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 17411C6C28F42AAA00B5A062 /* EasyListDeleteDeprecated.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EasyListDeleteDeprecated.swift; sourceTree = ""; }; + 2AC0FFBACB20C3862AB405EFAEB1A8DC /* EasyListView-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "EasyListView-prefix.pch"; sourceTree = ""; }; + 2E784486FB04AE932055287F32B01184 /* EasyListAppend.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = EasyListAppend.swift; sourceTree = ""; }; + 2F542C96399FF93278D0ED665AB6D12F /* EasyCompatible */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = EasyCompatible; path = EasyCompatible.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 3D7F3D2A8716D6B25B6347422DF1360A /* EasyListView.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = EasyListView.release.xcconfig; sourceTree = ""; }; + 3DC53F189D48F0DB7E5286809164F099 /* Pods-EasyListViewExample-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-EasyListViewExample-frameworks.sh"; sourceTree = ""; }; + 416EDBD62E0755546781C03B7860CDDF /* EasyListObjCDeprecated.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = EasyListObjCDeprecated.swift; sourceTree = ""; }; + 4A334FEF8D9968BEEEC7A322398B20B8 /* EasyListView-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "EasyListView-Info.plist"; sourceTree = ""; }; + 4B264D2E22EF6B920AD175EEE6716631 /* Pods-EasyListViewExample-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-EasyListViewExample-dummy.m"; sourceTree = ""; }; + 54683439F744C3B37AC2D6DA550CC8DC /* Pods-EasyListViewExample-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-EasyListViewExample-Info.plist"; sourceTree = ""; }; + 57C29B96E09DC7886E502442E9A283F1 /* Pods-EasyListViewExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-EasyListViewExample.debug.xcconfig"; sourceTree = ""; }; + 5AB3E8D42751D63D16E5ACED4E82E0D2 /* EasyListAppendDeprecated.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = EasyListAppendDeprecated.swift; sourceTree = ""; }; + 5B1795D2806A751242D819B67BC4B3BE /* EasyListDelete.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = EasyListDelete.swift; sourceTree = ""; }; + 5CF9FC8D859809A39070ADED10DF9BB9 /* Pods-EasyListViewExample-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-EasyListViewExample-umbrella.h"; sourceTree = ""; }; + 5D5D443D782B40187C4862ACB87A7D79 /* EasyCompatible.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = EasyCompatible.release.xcconfig; sourceTree = ""; }; + 5F90D60DEFC96AE8426C64F336098A81 /* EasyCompatible-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "EasyCompatible-dummy.m"; sourceTree = ""; }; + 6FD9AEEB09584CCD3BAFBA94AFBBC24E /* EasyListView.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; path = EasyListView.podspec; sourceTree = ""; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + 7204B0CB544C6B43C25AB0107A293CC7 /* EasyListView */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = EasyListView; path = EasyListView.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7222FDDDBAA6AF1BB57420FFF4BEBC06 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; + 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; + 73147B023A28EFD1FC94F7BFCA66F465 /* EasyListObjC.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = EasyListObjC.swift; sourceTree = ""; }; + 73CD48CD5DF5DC42B40934B4E929C0E0 /* EasyListInsert.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = EasyListInsert.swift; sourceTree = ""; }; + 8661B95EB38CE735F557FFE16B13F011 /* EasyListDisposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = EasyListDisposable.swift; sourceTree = ""; }; + 86936228286AF97E784A8EAB27CF9D64 /* EasyCompatible-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "EasyCompatible-prefix.pch"; sourceTree = ""; }; + 8E42FEFA8C924FB6935E427383154EF8 /* EasyListView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = EasyListView.swift; sourceTree = ""; }; + 99D14C850F6AF2956FE64C172356CBD6 /* EasyListView-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "EasyListView-umbrella.h"; sourceTree = ""; }; + 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + 9EF82100FC6DF9D8E5EAE09F637E9800 /* EasyCompatible.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = EasyCompatible.modulemap; sourceTree = ""; }; + A849A0B4ADA2FBD77A8DE6BAAB3307CF /* EasyListAttributes.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = EasyListAttributes.swift; sourceTree = ""; }; + ACC53AA1CC0A5DFD4504E4475CE94396 /* EasyListView.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = EasyListView.debug.xcconfig; sourceTree = ""; }; + B07E80928679111B5466AD8E37F68344 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; + BA0430F87E305402EFAE2A8A4C9471A5 /* EasyCompatible.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = EasyCompatible.swift; path = Sources/EasyCompatible.swift; sourceTree = ""; }; + BD9293767642F89624FD20C601E54337 /* Pods-EasyListViewExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-EasyListViewExample.release.xcconfig"; sourceTree = ""; }; + BE0B70180EBE80A97B39281C96688874 /* EasyCompatible.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = EasyCompatible.debug.xcconfig; sourceTree = ""; }; + C095D3E321BB651072C68F4A5762CC60 /* EasyListView-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "EasyListView-dummy.m"; sourceTree = ""; }; + C60C75EC6F467D828687161D7DC55275 /* EasyCompatible-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "EasyCompatible-umbrella.h"; sourceTree = ""; }; + C81ADED5DEB7DD854E0D394493FE1E57 /* EasyListInsertDeprecated.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = EasyListInsertDeprecated.swift; sourceTree = ""; }; + C9F62C0279CFA6F8ABF3F770AF084432 /* Pods-EasyListViewExample-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-EasyListViewExample-acknowledgements.markdown"; sourceTree = ""; }; + CEDFBE6E5D33A98697914EB2CAD707DA /* Pods-EasyListViewExample.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-EasyListViewExample.modulemap"; sourceTree = ""; }; + D3B48F0641D9C60E1B10A84062AF2A55 /* EasyListExtension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = EasyListExtension.swift; sourceTree = ""; }; + D792F934E4789FA2C4C651BFAF6878E5 /* EasyCompatible-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "EasyCompatible-Info.plist"; sourceTree = ""; }; + DDD4A2473CD1D8D57B1643134A6DFE1E /* EasyListView.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = EasyListView.modulemap; sourceTree = ""; }; + E9DD3F279F16CC4F6F4EF6337353671D /* Pods-EasyListViewExample */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = "Pods-EasyListViewExample"; path = Pods_EasyListViewExample.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + ECB870EF5E6EB31B18943F0821F1A82F /* EasyListConstraint.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = EasyListConstraint.swift; sourceTree = ""; }; + FA9FA2FF1FBF87EECACE649667A6E55C /* Pods-EasyListViewExample-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-EasyListViewExample-acknowledgements.plist"; sourceTree = ""; }; + FDFEAA6AC9D0AFDCFDC93DAC5CCCFBCC /* EasyListCoordinator.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = EasyListCoordinator.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 16E2A5F2DC91502A90E8CA10D7EBBE2E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 5F767BF2F404002B2C4B2A0A75D8D6FA /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C0F175B044399F75451CB2AECDB07B86 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 67E378D73F53EB5C4A8B9A29BC970F89 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D417A6A688E8C54ACBF41379740FB56C /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8B6BAFB81AF489707F7DB5A2AA6F3051 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1431546E49CA5E9CCF3B2B0542778F50 /* Targets Support Files */ = { + isa = PBXGroup; + children = ( + A07A7A47E83B3EE631EFFDD29E355275 /* Pods-EasyListViewExample */, + ); + name = "Targets Support Files"; + sourceTree = ""; + }; + 2774AA0B451A43777D6FAF95F14ABD33 /* Pods */ = { + isa = PBXGroup; + children = ( + A382D3DECE6B4A2A08B5A8F1E09F25FA /* EasyCompatible */, + ); + name = Pods; + sourceTree = ""; + }; + 4E12714667057C6A79E4EB09E76A2406 /* Products */ = { + isa = PBXGroup; + children = ( + 2F542C96399FF93278D0ED665AB6D12F /* EasyCompatible */, + 7204B0CB544C6B43C25AB0107A293CC7 /* EasyListView */, + E9DD3F279F16CC4F6F4EF6337353671D /* Pods-EasyListViewExample */, + ); + name = Products; + sourceTree = ""; + }; + 578452D2E740E91742655AC8F1636D1F /* iOS */ = { + isa = PBXGroup; + children = ( + 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */, + ); + name = iOS; + sourceTree = ""; + }; + 57B0D095826F4AD8EB6CDC1523531C40 /* ObjC */ = { + isa = PBXGroup; + children = ( + 73147B023A28EFD1FC94F7BFCA66F465 /* EasyListObjC.swift */, + 416EDBD62E0755546781C03B7860CDDF /* EasyListObjCDeprecated.swift */, + ); + name = ObjC; + path = Sources/ObjC; + sourceTree = ""; + }; + 6DCAF34C25863AAD4521043214B2D6F4 /* EasyListView */ = { + isa = PBXGroup; + children = ( + 57B0D095826F4AD8EB6CDC1523531C40 /* ObjC */, + D92AFDE3173E6488A3C9D1135EF0A590 /* Pod */, + FF908064ACAB4686B10807B096B97B4D /* Support Files */, + C94EF3D8BCE2AAC1E949FFA4118128EF /* Swift */, + ); + name = EasyListView; + path = ..; + sourceTree = ""; + }; + A07A7A47E83B3EE631EFFDD29E355275 /* Pods-EasyListViewExample */ = { + isa = PBXGroup; + children = ( + CEDFBE6E5D33A98697914EB2CAD707DA /* Pods-EasyListViewExample.modulemap */, + C9F62C0279CFA6F8ABF3F770AF084432 /* Pods-EasyListViewExample-acknowledgements.markdown */, + FA9FA2FF1FBF87EECACE649667A6E55C /* Pods-EasyListViewExample-acknowledgements.plist */, + 4B264D2E22EF6B920AD175EEE6716631 /* Pods-EasyListViewExample-dummy.m */, + 3DC53F189D48F0DB7E5286809164F099 /* Pods-EasyListViewExample-frameworks.sh */, + 54683439F744C3B37AC2D6DA550CC8DC /* Pods-EasyListViewExample-Info.plist */, + 5CF9FC8D859809A39070ADED10DF9BB9 /* Pods-EasyListViewExample-umbrella.h */, + 57C29B96E09DC7886E502442E9A283F1 /* Pods-EasyListViewExample.debug.xcconfig */, + BD9293767642F89624FD20C601E54337 /* Pods-EasyListViewExample.release.xcconfig */, + ); + name = "Pods-EasyListViewExample"; + path = "Target Support Files/Pods-EasyListViewExample"; + sourceTree = ""; + }; + A382D3DECE6B4A2A08B5A8F1E09F25FA /* EasyCompatible */ = { + isa = PBXGroup; + children = ( + BA0430F87E305402EFAE2A8A4C9471A5 /* EasyCompatible.swift */, + D190C0FDD4A86B98E6E09710B055D8FA /* Support Files */, + ); + path = EasyCompatible; + sourceTree = ""; + }; + C94EF3D8BCE2AAC1E949FFA4118128EF /* Swift */ = { + isa = PBXGroup; + children = ( + 2E784486FB04AE932055287F32B01184 /* EasyListAppend.swift */, + 5AB3E8D42751D63D16E5ACED4E82E0D2 /* EasyListAppendDeprecated.swift */, + A849A0B4ADA2FBD77A8DE6BAAB3307CF /* EasyListAttributes.swift */, + ECB870EF5E6EB31B18943F0821F1A82F /* EasyListConstraint.swift */, + FDFEAA6AC9D0AFDCFDC93DAC5CCCFBCC /* EasyListCoordinator.swift */, + 5B1795D2806A751242D819B67BC4B3BE /* EasyListDelete.swift */, + 8661B95EB38CE735F557FFE16B13F011 /* EasyListDisposable.swift */, + D3B48F0641D9C60E1B10A84062AF2A55 /* EasyListExtension.swift */, + 73CD48CD5DF5DC42B40934B4E929C0E0 /* EasyListInsert.swift */, + C81ADED5DEB7DD854E0D394493FE1E57 /* EasyListInsertDeprecated.swift */, + 8E42FEFA8C924FB6935E427383154EF8 /* EasyListView.swift */, + 17411C6C28F42AAA00B5A062 /* EasyListDeleteDeprecated.swift */, + ); + name = Swift; + path = Sources/Swift; + sourceTree = ""; + }; + CF1408CF629C7361332E53B88F7BD30C = { + isa = PBXGroup; + children = ( + 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */, + E03184A229EFDE04FC29B4243669B5A0 /* Development Pods */, + D210D550F4EA176C3123ED886F8F87F5 /* Frameworks */, + 2774AA0B451A43777D6FAF95F14ABD33 /* Pods */, + 4E12714667057C6A79E4EB09E76A2406 /* Products */, + 1431546E49CA5E9CCF3B2B0542778F50 /* Targets Support Files */, + ); + sourceTree = ""; + }; + D190C0FDD4A86B98E6E09710B055D8FA /* Support Files */ = { + isa = PBXGroup; + children = ( + 9EF82100FC6DF9D8E5EAE09F637E9800 /* EasyCompatible.modulemap */, + 5F90D60DEFC96AE8426C64F336098A81 /* EasyCompatible-dummy.m */, + D792F934E4789FA2C4C651BFAF6878E5 /* EasyCompatible-Info.plist */, + 86936228286AF97E784A8EAB27CF9D64 /* EasyCompatible-prefix.pch */, + C60C75EC6F467D828687161D7DC55275 /* EasyCompatible-umbrella.h */, + BE0B70180EBE80A97B39281C96688874 /* EasyCompatible.debug.xcconfig */, + 5D5D443D782B40187C4862ACB87A7D79 /* EasyCompatible.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/EasyCompatible"; + sourceTree = ""; + }; + D210D550F4EA176C3123ED886F8F87F5 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 578452D2E740E91742655AC8F1636D1F /* iOS */, + ); + name = Frameworks; + sourceTree = ""; + }; + D92AFDE3173E6488A3C9D1135EF0A590 /* Pod */ = { + isa = PBXGroup; + children = ( + 6FD9AEEB09584CCD3BAFBA94AFBBC24E /* EasyListView.podspec */, + 7222FDDDBAA6AF1BB57420FFF4BEBC06 /* LICENSE */, + B07E80928679111B5466AD8E37F68344 /* README.md */, + ); + name = Pod; + sourceTree = ""; + }; + E03184A229EFDE04FC29B4243669B5A0 /* Development Pods */ = { + isa = PBXGroup; + children = ( + 6DCAF34C25863AAD4521043214B2D6F4 /* EasyListView */, + ); + name = "Development Pods"; + sourceTree = ""; + }; + FF908064ACAB4686B10807B096B97B4D /* Support Files */ = { + isa = PBXGroup; + children = ( + DDD4A2473CD1D8D57B1643134A6DFE1E /* EasyListView.modulemap */, + C095D3E321BB651072C68F4A5762CC60 /* EasyListView-dummy.m */, + 4A334FEF8D9968BEEEC7A322398B20B8 /* EasyListView-Info.plist */, + 2AC0FFBACB20C3862AB405EFAEB1A8DC /* EasyListView-prefix.pch */, + 99D14C850F6AF2956FE64C172356CBD6 /* EasyListView-umbrella.h */, + ACC53AA1CC0A5DFD4504E4475CE94396 /* EasyListView.debug.xcconfig */, + 3D7F3D2A8716D6B25B6347422DF1360A /* EasyListView.release.xcconfig */, + ); + name = "Support Files"; + path = "Pods/Target Support Files/EasyListView"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 2732A5FCDD599D1B13C315DF6DF829A7 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + F9DE1A101BA450BD5D9A39A5D3A0ADCE /* EasyListView-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E0D0894A7A8AB5AB65C0DF4C095F9D82 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 397820FAF75252EEDA61C15837D2BD2F /* EasyCompatible-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F4AED32EE0AF8EFF7BAF3E4B0C4DDEBF /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + CE5BA9255696976AD15BB916DE6F9740 /* Pods-EasyListViewExample-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 158B7ADE69A453707A560D6EA60C90AF /* EasyListView */ = { + isa = PBXNativeTarget; + buildConfigurationList = B7CACE13254CAC0B16E06D6DC2CCF7B3 /* Build configuration list for PBXNativeTarget "EasyListView" */; + buildPhases = ( + 2732A5FCDD599D1B13C315DF6DF829A7 /* Headers */, + 29DC8889A5DB7D9E687BC661F486D58D /* Sources */, + D417A6A688E8C54ACBF41379740FB56C /* Frameworks */, + C911F1D226C29BCD5844D5808B510564 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + E92D04CBF1AB8E262B3F5F0A2B2D0270 /* PBXTargetDependency */, + ); + name = EasyListView; + productName = EasyListView; + productReference = 7204B0CB544C6B43C25AB0107A293CC7 /* EasyListView */; + productType = "com.apple.product-type.framework"; + }; + 6D0949614762ADA89669D857188A9171 /* EasyCompatible */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7494EB81BC1E7187586D48AD6A3E89AF /* Build configuration list for PBXNativeTarget "EasyCompatible" */; + buildPhases = ( + E0D0894A7A8AB5AB65C0DF4C095F9D82 /* Headers */, + 570DC3C2F3D5951411AE6DF93CD58416 /* Sources */, + 16E2A5F2DC91502A90E8CA10D7EBBE2E /* Frameworks */, + 2D043534B78AC0D6111D6D05EBE5BD30 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = EasyCompatible; + productName = EasyCompatible; + productReference = 2F542C96399FF93278D0ED665AB6D12F /* EasyCompatible */; + productType = "com.apple.product-type.framework"; + }; + C3E606294D7FDE9AD7ACA587FBD3DBF5 /* Pods-EasyListViewExample */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7EE703A1C141ED198C307BE833DF5DDF /* Build configuration list for PBXNativeTarget "Pods-EasyListViewExample" */; + buildPhases = ( + F4AED32EE0AF8EFF7BAF3E4B0C4DDEBF /* Headers */, + 987BFB08FF2E34830C1E324CD0A3A04D /* Sources */, + C0F175B044399F75451CB2AECDB07B86 /* Frameworks */, + 89E3AC348C984392E24BACA30EA22489 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + E9CF33FC073F27E89ED1A6D137907FCA /* PBXTargetDependency */, + 525D44F6AB1258AAB497B30D72B8161F /* PBXTargetDependency */, + ); + name = "Pods-EasyListViewExample"; + productName = Pods_EasyListViewExample; + productReference = E9DD3F279F16CC4F6F4EF6337353671D /* Pods-EasyListViewExample */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + BFDFE7DC352907FC980B868725387E98 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1240; + LastUpgradeCheck = 1240; + }; + buildConfigurationList = 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + Base, + en, + ); + mainGroup = CF1408CF629C7361332E53B88F7BD30C; + productRefGroup = 4E12714667057C6A79E4EB09E76A2406 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 6D0949614762ADA89669D857188A9171 /* EasyCompatible */, + 158B7ADE69A453707A560D6EA60C90AF /* EasyListView */, + C3E606294D7FDE9AD7ACA587FBD3DBF5 /* Pods-EasyListViewExample */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 2D043534B78AC0D6111D6D05EBE5BD30 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 89E3AC348C984392E24BACA30EA22489 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C911F1D226C29BCD5844D5808B510564 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 29DC8889A5DB7D9E687BC661F486D58D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + AA3C6828E485A58A93E52418D1915630 /* EasyListAppend.swift in Sources */, + 0FA2863A558AD78D8A97097AC9FCCAC3 /* EasyListAppendDeprecated.swift in Sources */, + 4EF181BD4F9D36244719893D56EB9B6D /* EasyListAttributes.swift in Sources */, + 17411C6D28F42AAA00B5A062 /* EasyListDeleteDeprecated.swift in Sources */, + 5E0EC6C11928235E98EA24947BE8C84B /* EasyListConstraint.swift in Sources */, + 5A0802CA3EE27D194452AECAC40E9214 /* EasyListCoordinator.swift in Sources */, + DF97D4A0989DDA2470FD5F23859F9229 /* EasyListDelete.swift in Sources */, + D55F768A2B9A23627156126C949D5986 /* EasyListDisposable.swift in Sources */, + C22F7FD6E05EC6895B2752A478F33E21 /* EasyListExtension.swift in Sources */, + F130EA94A1683AA2912B59A66A0CD96E /* EasyListInsert.swift in Sources */, + F4C04535A58E9EDF3D0481B4BE52E710 /* EasyListInsertDeprecated.swift in Sources */, + 17ACACC0376B5CD47345C9B0011B26AE /* EasyListObjC.swift in Sources */, + A94A70751AF61E0AA739BA290110092A /* EasyListObjCDeprecated.swift in Sources */, + 580C01C8B90466ED0BF5584957A8047E /* EasyListView.swift in Sources */, + B52AEFFD16A78EC2FF6684EA1312607E /* EasyListView-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 570DC3C2F3D5951411AE6DF93CD58416 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5C7C0F684425C19D4D7E86A1177DF6AD /* EasyCompatible.swift in Sources */, + ED4E63541BDEB3C59330DBD18C108CA9 /* EasyCompatible-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 987BFB08FF2E34830C1E324CD0A3A04D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C9E4311192E54AB7354DB8100AB1B4F6 /* Pods-EasyListViewExample-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 525D44F6AB1258AAB497B30D72B8161F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = EasyListView; + target = 158B7ADE69A453707A560D6EA60C90AF /* EasyListView */; + targetProxy = BEF977E3A8A2F8E12EE5C1B586D7FD04 /* PBXContainerItemProxy */; + }; + E92D04CBF1AB8E262B3F5F0A2B2D0270 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = EasyCompatible; + target = 6D0949614762ADA89669D857188A9171 /* EasyCompatible */; + targetProxy = BCCAEBEA43A7A8C5B7C805698B715187 /* PBXContainerItemProxy */; + }; + E9CF33FC073F27E89ED1A6D137907FCA /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = EasyCompatible; + target = 6D0949614762ADA89669D857188A9171 /* EasyCompatible */; + targetProxy = B10B0FDC2AA0BD659771D029B566916D /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 07560150D45B13A90167AF8A467C0901 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = BD9293767642F89624FD20C601E54337 /* Pods-EasyListViewExample.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 13DB69AB6B7383AA0A7ECEEF3391298C /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = ACC53AA1CC0A5DFD4504E4475CE94396 /* EasyListView.debug.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/EasyListView/EasyListView-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/EasyListView/EasyListView-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/EasyListView/EasyListView.modulemap"; + PRODUCT_MODULE_NAME = EasyListView; + PRODUCT_NAME = EasyListView; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 15BCAAE6BBE846D043F2CB6F6144F14D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 5D5D443D782B40187C4862ACB87A7D79 /* EasyCompatible.release.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/EasyCompatible/EasyCompatible-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/EasyCompatible/EasyCompatible-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/EasyCompatible/EasyCompatible.modulemap"; + PRODUCT_MODULE_NAME = EasyCompatible; + PRODUCT_NAME = EasyCompatible; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 25AD9454612BF454A1E3DC4CD4FA8C6D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "POD_CONFIGURATION_DEBUG=1", + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + STRIP_INSTALLED_PRODUCT = NO; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + SYMROOT = "${SRCROOT}/../build"; + }; + name = Debug; + }; + B55BE61A94ABCB0F5127F28C42A86EDC /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 3D7F3D2A8716D6B25B6347422DF1360A /* EasyListView.release.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/EasyListView/EasyListView-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/EasyListView/EasyListView-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/EasyListView/EasyListView.modulemap"; + PRODUCT_MODULE_NAME = EasyListView; + PRODUCT_NAME = EasyListView; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + BC752B815B5ECC54367F0B2BBFA2B62B /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 57C29B96E09DC7886E502442E9A283F1 /* Pods-EasyListViewExample.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + CA547D2C7E9A8A153DC2B27FBE00B112 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "POD_CONFIGURATION_RELEASE=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + STRIP_INSTALLED_PRODUCT = NO; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 5.0; + SYMROOT = "${SRCROOT}/../build"; + }; + name = Release; + }; + EDAB50B88C26539E4A8EED3847625034 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = BE0B70180EBE80A97B39281C96688874 /* EasyCompatible.debug.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/EasyCompatible/EasyCompatible-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/EasyCompatible/EasyCompatible-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/EasyCompatible/EasyCompatible.modulemap"; + PRODUCT_MODULE_NAME = EasyCompatible; + PRODUCT_NAME = EasyCompatible; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 25AD9454612BF454A1E3DC4CD4FA8C6D /* Debug */, + CA547D2C7E9A8A153DC2B27FBE00B112 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 7494EB81BC1E7187586D48AD6A3E89AF /* Build configuration list for PBXNativeTarget "EasyCompatible" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + EDAB50B88C26539E4A8EED3847625034 /* Debug */, + 15BCAAE6BBE846D043F2CB6F6144F14D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 7EE703A1C141ED198C307BE833DF5DDF /* Build configuration list for PBXNativeTarget "Pods-EasyListViewExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + BC752B815B5ECC54367F0B2BBFA2B62B /* Debug */, + 07560150D45B13A90167AF8A467C0901 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B7CACE13254CAC0B16E06D6DC2CCF7B3 /* Build configuration list for PBXNativeTarget "EasyListView" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 13DB69AB6B7383AA0A7ECEEF3391298C /* Debug */, + B55BE61A94ABCB0F5127F28C42A86EDC /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = BFDFE7DC352907FC980B868725387E98 /* Project object */; +} diff --git a/Pods/Target Support Files/EasyCompatible/EasyCompatible-Info.plist b/Pods/Target Support Files/EasyCompatible/EasyCompatible-Info.plist new file mode 100644 index 0000000..2243fe6 --- /dev/null +++ b/Pods/Target Support Files/EasyCompatible/EasyCompatible-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/EasyCompatible/EasyCompatible-dummy.m b/Pods/Target Support Files/EasyCompatible/EasyCompatible-dummy.m new file mode 100644 index 0000000..963dd10 --- /dev/null +++ b/Pods/Target Support Files/EasyCompatible/EasyCompatible-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_EasyCompatible : NSObject +@end +@implementation PodsDummy_EasyCompatible +@end diff --git a/Pods/Target Support Files/EasyCompatible/EasyCompatible-prefix.pch b/Pods/Target Support Files/EasyCompatible/EasyCompatible-prefix.pch new file mode 100644 index 0000000..beb2a24 --- /dev/null +++ b/Pods/Target Support Files/EasyCompatible/EasyCompatible-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/Pods/Target Support Files/EasyCompatible/EasyCompatible-umbrella.h b/Pods/Target Support Files/EasyCompatible/EasyCompatible-umbrella.h new file mode 100644 index 0000000..9dac010 --- /dev/null +++ b/Pods/Target Support Files/EasyCompatible/EasyCompatible-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double EasyCompatibleVersionNumber; +FOUNDATION_EXPORT const unsigned char EasyCompatibleVersionString[]; + diff --git a/Pods/Target Support Files/EasyCompatible/EasyCompatible.debug.xcconfig b/Pods/Target Support Files/EasyCompatible/EasyCompatible.debug.xcconfig new file mode 100644 index 0000000..4b732d9 --- /dev/null +++ b/Pods/Target Support Files/EasyCompatible/EasyCompatible.debug.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/EasyCompatible +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/EasyCompatible +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/EasyCompatible/EasyCompatible.modulemap b/Pods/Target Support Files/EasyCompatible/EasyCompatible.modulemap new file mode 100644 index 0000000..bac0444 --- /dev/null +++ b/Pods/Target Support Files/EasyCompatible/EasyCompatible.modulemap @@ -0,0 +1,6 @@ +framework module EasyCompatible { + umbrella header "EasyCompatible-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/EasyCompatible/EasyCompatible.release.xcconfig b/Pods/Target Support Files/EasyCompatible/EasyCompatible.release.xcconfig new file mode 100644 index 0000000..4b732d9 --- /dev/null +++ b/Pods/Target Support Files/EasyCompatible/EasyCompatible.release.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/EasyCompatible +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/EasyCompatible +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/EasyListView/EasyListView-Info.plist b/Pods/Target Support Files/EasyListView/EasyListView-Info.plist new file mode 100644 index 0000000..b6b2813 --- /dev/null +++ b/Pods/Target Support Files/EasyListView/EasyListView-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.3.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/EasyListView/EasyListView-dummy.m b/Pods/Target Support Files/EasyListView/EasyListView-dummy.m new file mode 100644 index 0000000..bc8181f --- /dev/null +++ b/Pods/Target Support Files/EasyListView/EasyListView-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_EasyListView : NSObject +@end +@implementation PodsDummy_EasyListView +@end diff --git a/Pods/Target Support Files/EasyListView/EasyListView-prefix.pch b/Pods/Target Support Files/EasyListView/EasyListView-prefix.pch new file mode 100644 index 0000000..beb2a24 --- /dev/null +++ b/Pods/Target Support Files/EasyListView/EasyListView-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/Pods/Target Support Files/EasyListView/EasyListView-umbrella.h b/Pods/Target Support Files/EasyListView/EasyListView-umbrella.h new file mode 100644 index 0000000..8ad5757 --- /dev/null +++ b/Pods/Target Support Files/EasyListView/EasyListView-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double EasyListViewVersionNumber; +FOUNDATION_EXPORT const unsigned char EasyListViewVersionString[]; + diff --git a/Pods/Target Support Files/EasyListView/EasyListView.debug.xcconfig b/Pods/Target Support Files/EasyListView/EasyListView.debug.xcconfig new file mode 100644 index 0000000..8931318 --- /dev/null +++ b/Pods/Target Support Files/EasyListView/EasyListView.debug.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/EasyListView +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/EasyCompatible" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "EasyCompatible" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/.. +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/EasyListView/EasyListView.modulemap b/Pods/Target Support Files/EasyListView/EasyListView.modulemap new file mode 100644 index 0000000..3847354 --- /dev/null +++ b/Pods/Target Support Files/EasyListView/EasyListView.modulemap @@ -0,0 +1,6 @@ +framework module EasyListView { + umbrella header "EasyListView-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/EasyListView/EasyListView.release.xcconfig b/Pods/Target Support Files/EasyListView/EasyListView.release.xcconfig new file mode 100644 index 0000000..8931318 --- /dev/null +++ b/Pods/Target Support Files/EasyListView/EasyListView.release.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/EasyListView +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/EasyCompatible" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "EasyCompatible" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/.. +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-Info.plist b/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-Info.plist new file mode 100644 index 0000000..2243fe6 --- /dev/null +++ b/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-acknowledgements.markdown b/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-acknowledgements.markdown new file mode 100644 index 0000000..889f440 --- /dev/null +++ b/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-acknowledgements.markdown @@ -0,0 +1,53 @@ +# Acknowledgements +This application makes use of the following third party libraries: + +## EasyCompatible + +MIT License + +Copyright (c) 2022 moliya + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +## EasyListView + +MIT License + +Copyright (c) 2020 moliya + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +Generated by CocoaPods - https://cocoapods.org diff --git a/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-acknowledgements.plist b/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-acknowledgements.plist new file mode 100644 index 0000000..4880b11 --- /dev/null +++ b/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-acknowledgements.plist @@ -0,0 +1,91 @@ + + + + + PreferenceSpecifiers + + + FooterText + This application makes use of the following third party libraries: + Title + Acknowledgements + Type + PSGroupSpecifier + + + FooterText + MIT License + +Copyright (c) 2022 moliya + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + License + MIT + Title + EasyCompatible + Type + PSGroupSpecifier + + + FooterText + MIT License + +Copyright (c) 2020 moliya + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + License + MIT + Title + EasyListView + Type + PSGroupSpecifier + + + FooterText + Generated by CocoaPods - https://cocoapods.org + Title + + Type + PSGroupSpecifier + + + StringsTable + Acknowledgements + Title + Acknowledgements + + diff --git a/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-dummy.m b/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-dummy.m new file mode 100644 index 0000000..421b2ff --- /dev/null +++ b/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_EasyListViewExample : NSObject +@end +@implementation PodsDummy_Pods_EasyListViewExample +@end diff --git a/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-frameworks-Debug-input-files.xcfilelist b/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-frameworks-Debug-input-files.xcfilelist new file mode 100644 index 0000000..0549d69 --- /dev/null +++ b/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-frameworks-Debug-input-files.xcfilelist @@ -0,0 +1,3 @@ +${PODS_ROOT}/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-frameworks.sh +${BUILT_PRODUCTS_DIR}/EasyCompatible/EasyCompatible.framework +${BUILT_PRODUCTS_DIR}/EasyListView/EasyListView.framework \ No newline at end of file diff --git a/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-frameworks-Debug-output-files.xcfilelist b/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-frameworks-Debug-output-files.xcfilelist new file mode 100644 index 0000000..fb2fe6d --- /dev/null +++ b/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-frameworks-Debug-output-files.xcfilelist @@ -0,0 +1,2 @@ +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/EasyCompatible.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/EasyListView.framework \ No newline at end of file diff --git a/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-frameworks-Release-input-files.xcfilelist b/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-frameworks-Release-input-files.xcfilelist new file mode 100644 index 0000000..0549d69 --- /dev/null +++ b/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-frameworks-Release-input-files.xcfilelist @@ -0,0 +1,3 @@ +${PODS_ROOT}/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-frameworks.sh +${BUILT_PRODUCTS_DIR}/EasyCompatible/EasyCompatible.framework +${BUILT_PRODUCTS_DIR}/EasyListView/EasyListView.framework \ No newline at end of file diff --git a/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-frameworks-Release-output-files.xcfilelist b/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-frameworks-Release-output-files.xcfilelist new file mode 100644 index 0000000..fb2fe6d --- /dev/null +++ b/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-frameworks-Release-output-files.xcfilelist @@ -0,0 +1,2 @@ +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/EasyCompatible.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/EasyListView.framework \ No newline at end of file diff --git a/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-frameworks.sh b/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-frameworks.sh new file mode 100755 index 0000000..d0bbd30 --- /dev/null +++ b/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-frameworks.sh @@ -0,0 +1,188 @@ +#!/bin/sh +set -e +set -u +set -o pipefail + +function on_error { + echo "$(realpath -mq "${0}"):$1: error: Unexpected failure" +} +trap 'on_error $LINENO' ERR + +if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then + # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy + # frameworks to, so exit 0 (signalling the script phase was successful). + exit 0 +fi + +echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" +mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + +COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" +SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" +BCSYMBOLMAP_DIR="BCSymbolMaps" + + +# This protects against multiple targets copying the same framework dependency at the same time. The solution +# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html +RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") + +# Copies and strips a vendored framework +install_framework() +{ + if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then + local source="${BUILT_PRODUCTS_DIR}/$1" + elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then + local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" + elif [ -r "$1" ]; then + local source="$1" + fi + + local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + + if [ -L "${source}" ]; then + echo "Symlinked..." + source="$(readlink "${source}")" + fi + + if [ -d "${source}/${BCSYMBOLMAP_DIR}" ]; then + # Locate and install any .bcsymbolmaps if present, and remove them from the .framework before the framework is copied + find "${source}/${BCSYMBOLMAP_DIR}" -name "*.bcsymbolmap"|while read f; do + echo "Installing $f" + install_bcsymbolmap "$f" "$destination" + rm "$f" + done + rmdir "${source}/${BCSYMBOLMAP_DIR}" + fi + + # Use filter instead of exclude so missing patterns don't throw errors. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" + + local basename + basename="$(basename -s .framework "$1")" + binary="${destination}/${basename}.framework/${basename}" + + if ! [ -r "$binary" ]; then + binary="${destination}/${basename}" + elif [ -L "${binary}" ]; then + echo "Destination binary is symlinked..." + dirname="$(dirname "${binary}")" + binary="${dirname}/$(readlink "${binary}")" + fi + + # Strip invalid architectures so "fat" simulator / device frameworks work on device + if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then + strip_invalid_archs "$binary" + fi + + # Resign the code if required by the build settings to avoid unstable apps + code_sign_if_enabled "${destination}/$(basename "$1")" + + # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. + if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then + local swift_runtime_libs + swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u) + for lib in $swift_runtime_libs; do + echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" + rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" + code_sign_if_enabled "${destination}/${lib}" + done + fi +} +# Copies and strips a vendored dSYM +install_dsym() { + local source="$1" + warn_missing_arch=${2:-true} + if [ -r "$source" ]; then + # Copy the dSYM into the targets temp dir. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" + + local basename + basename="$(basename -s .dSYM "$source")" + binary_name="$(ls "$source/Contents/Resources/DWARF")" + binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}" + + # Strip invalid architectures from the dSYM. + if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then + strip_invalid_archs "$binary" "$warn_missing_arch" + fi + if [[ $STRIP_BINARY_RETVAL == 0 ]]; then + # Move the stripped file into its final destination. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}" + else + # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. + mkdir -p "${DWARF_DSYM_FOLDER_PATH}" + touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM" + fi + fi +} + +# Used as a return value for each invocation of `strip_invalid_archs` function. +STRIP_BINARY_RETVAL=0 + +# Strip invalid architectures +strip_invalid_archs() { + binary="$1" + warn_missing_arch=${2:-true} + # Get architectures for current target binary + binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" + # Intersect them with the architectures we are building for + intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" + # If there are no archs supported by this binary then warn the user + if [[ -z "$intersected_archs" ]]; then + if [[ "$warn_missing_arch" == "true" ]]; then + echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." + fi + STRIP_BINARY_RETVAL=1 + return + fi + stripped="" + for arch in $binary_archs; do + if ! [[ "${ARCHS}" == *"$arch"* ]]; then + # Strip non-valid architectures in-place + lipo -remove "$arch" -output "$binary" "$binary" + stripped="$stripped $arch" + fi + done + if [[ "$stripped" ]]; then + echo "Stripped $binary of architectures:$stripped" + fi + STRIP_BINARY_RETVAL=0 +} + +# Copies the bcsymbolmap files of a vendored framework +install_bcsymbolmap() { + local bcsymbolmap_path="$1" + local destination="${BUILT_PRODUCTS_DIR}" + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}" +} + +# Signs a framework with the provided identity +code_sign_if_enabled() { + if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then + # Use the current code_sign_identity + echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" + local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" + + if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + code_sign_cmd="$code_sign_cmd &" + fi + echo "$code_sign_cmd" + eval "$code_sign_cmd" + fi +} + +if [[ "$CONFIGURATION" == "Debug" ]]; then + install_framework "${BUILT_PRODUCTS_DIR}/EasyCompatible/EasyCompatible.framework" + install_framework "${BUILT_PRODUCTS_DIR}/EasyListView/EasyListView.framework" +fi +if [[ "$CONFIGURATION" == "Release" ]]; then + install_framework "${BUILT_PRODUCTS_DIR}/EasyCompatible/EasyCompatible.framework" + install_framework "${BUILT_PRODUCTS_DIR}/EasyListView/EasyListView.framework" +fi +if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + wait +fi diff --git a/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-umbrella.h b/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-umbrella.h new file mode 100644 index 0000000..0085806 --- /dev/null +++ b/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double Pods_EasyListViewExampleVersionNumber; +FOUNDATION_EXPORT const unsigned char Pods_EasyListViewExampleVersionString[]; + diff --git a/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample.debug.xcconfig b/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample.debug.xcconfig new file mode 100644 index 0000000..6d2ea23 --- /dev/null +++ b/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample.debug.xcconfig @@ -0,0 +1,15 @@ +ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/EasyCompatible" "${PODS_CONFIGURATION_BUILD_DIR}/EasyListView" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/EasyCompatible/EasyCompatible.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/EasyListView/EasyListView.framework/Headers" +LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "EasyCompatible" -framework "EasyListView" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample.modulemap b/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample.modulemap new file mode 100644 index 0000000..7230868 --- /dev/null +++ b/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample.modulemap @@ -0,0 +1,6 @@ +framework module Pods_EasyListViewExample { + umbrella header "Pods-EasyListViewExample-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample.release.xcconfig b/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample.release.xcconfig new file mode 100644 index 0000000..6d2ea23 --- /dev/null +++ b/Pods/Target Support Files/Pods-EasyListViewExample/Pods-EasyListViewExample.release.xcconfig @@ -0,0 +1,15 @@ +ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/EasyCompatible" "${PODS_CONFIGURATION_BUILD_DIR}/EasyListView" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/EasyCompatible/EasyCompatible.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/EasyListView/EasyListView.framework/Headers" +LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' +LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "EasyCompatible" -framework "EasyListView" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/README.md b/README.md index 164afee..6b18f14 100644 --- a/README.md +++ b/README.md @@ -30,80 +30,239 @@ 注意: EasyListView是通过约束实现自动布局的,支持高度自适应,请确保子视图添加了有效的约束(必要的高度约束或者intrinsicContentSize),以保证布局的正确性 ``` -##### Append +#### Append -用于往列表中添加子视图,无动画效果 +用于往列表中添加子视图 -```swift -//添加一个UILabel -let label = UILabel() -label.text = "Title" -self.scrollView.easy.append(label) -``` +- 使用Swift -```swift -//添加一个UILabel,与上一个视图间距16,并指定标识 -let label = UILabel() -label.text = "Title" -self.scrollView.easy.append(label, for: "titleLabel", spacing: 16) -``` + ```swift + //添加一个UILabel + let label = UILabel() + label.text = "Title" + scrollView.easy.appendView(label) + ``` -```swift -//添加一个UILabel,并指定四边间距 -let label = UILabel() -label.text = "Title" -self.scrollView.easy.append(label, with: UIEdgeInsets(top: 10, left: 16, bottom: 10, right: 16)) -``` + ```swift + //通过闭包方式添加一个UILabel + scrollView.easy.appendView { + let label = UILabel() + label.text = "Title" + return label + } + ``` -##### Insert +- 使用Objective-C -用于往列表中插入子视图,带动画效果 + ```objective-c + //添加一个UILabel + UILabel *label = [[UILabel alloc] init]; + label.text = @"Title"; + [scrollView easy_appendView:label]; + ``` -* 插入到某个视图对象之后,如果该对象有指定标识,可以传入String标识找到 + ```objective-c + //通过Block方式添加一个UILabel + [scrollView easy_appendViewBy:^UIView * _Nonnull{ + UILabel *label = [[UILabel alloc] init]; + label.text = @"Title"; + return label; + }]; + ``` -```swift -//在子视图label之后插入一个UITextField -let textField = UITextField() -self.scrollView.easy.insert(textField, after: label) -``` +#### Insert -```swift -//在标识为"Title"的子视图之后插入一个UITextField -let textField = UITextField() -self.scrollView.easy.insert(textField, after: "Title") -``` +用于往列表中插入子视图 -* 插入到某个视图对象之前 +* 插入到某个视图对象之后,如果该对象有指定标识,可以传入String标识找到 -```swift -//在子视图label之前插入一个UITextField -let textField = UITextField() -self.scrollView.easy.insert(textField, before: label) -``` + 使用Swift + + ```swift + //在子视图label之后插入一个UITextField + scrollView.easy.insertView(UITextField(), after: label) + //在子视图image之后插入一个UILabel + scrollView.easy.insertView(UILabel(), after: "image") + + //通过闭包方式在子视图label之后插入一个UITextField + scrollView.easy.insertView({ + return UITextField() + }, after: label) + //通过闭包方式在子视图image之后插入一个UILabel + scrollView.easy.insertView({ + let label = UILabel() + label.text = "Title" + return label + }, after: "image") + ``` + + 使用Objective-C + + ```objective-c + //在子视图label之后插入一个UITextField + [scrollView easy_insertView:[[UITextField alloc] init] after:label]; + //在子视图image之后插入一个UILabel + [scrollView easy_insertView:[[UILabel alloc] init] after:@"image"]; + + //通过Block方式在子视图label之后插入一个UITextField + [scrollView easy_insertViewBy:^UIView * _Nonnull{ + return [[UITextField alloc] init]; + } after:label]; + //通过Block方式在子视图image之后插入一个UILabel + [scrollView easy_insertViewBy:^UIView * _Nonnull{ + UILabel *label = [[UILabel alloc] init]; + label.text = @"Title"; + return label; + } after:@"image"]; + ``` -```swift -//在自身UIScrollView之前插入一个UITextField,即在末尾插入子视图 -let textField = UITextField() -self.scrollView.easy.insert(textField, before: self.scrollView) -``` +* 插入到某个视图对象之前 -##### Delete + 使用Swift + + ```swift + //在子视图label之前插入一个UITextField + scrollView.easy.insertView(UITextField(), before: label) + //在子视图image之前插入一个UILabel + scrollView.easy.insertView(UILabel(), before: "image") + + //在子视图label之前插入一个UITextField,使用闭包方式 + scrollView.easy.insertView({ + return UITextField() + }, before: label) + //在子视图image之前插入一个UILabel,使用闭包方式 + scrollView.easy.insertView({ + let label = UILabel() + label.text = "Title" + return label + }, before: "image") + ``` + + 使用Objective-C + + ```objective-c + //在子视图label之前插入一个UITextField + [scrollView easy_insertView:[[UITextField alloc] init] before:label]; + //在子视图image之前插入一个UILabel + [scrollView easy_insertView:[[UILabel alloc] init] before:@"image"]; + + //通过Block方式在子视图label之前插入一个UITextField + [scrollView easy_insertViewBy:^UIView * _Nonnull{ + return [[UITextField alloc] init]; + } before:label]; + //通过Block方式在子视图image之前插入一个UILabel + [scrollView easy_insertViewBy:^UIView * _Nonnull{ + UILabel *label = [[UILabel alloc] init]; + label.text = @"Title"; + return label; + } before:@"image"]; + ``` + +#### Attributes + +`Append`和`Insert`的视图支持以下自定义属性 + +1. identifier + + 设置唯一标识 + +2. insets + + 设置内间距,默认为zero + +3. spacing + + 设置与上一元素的间距,默认为0 + +4. clipsToBounds + + 设置超出部分是否裁剪,默认为true + +使用示例 + +- 使用Swift + + ```swift + scrollView.easy + .appendView(UILabel()) + .identifier("Label") + .insets(UIEdgeInsets(top: 10, left: 16, bottom: 0, right: 16)) + .clipsToBounds(true) + + scrollView.easy + .insertView(UIImageView(), after: "Label") + .spacing(20) + .clipsToBounds(false) + + scrollView.easy.appendView { + return UILabel() + } + .identifier("Label") + .insets(UIEdgeInsets(top: 10, left: 16, bottom: 0, right: 16)) + + scrollView.easy.insertView({ + return UIImageView() + }, after: "Label") + .spacing(20) + .clipsToBounds(false) + ``` + +- 使用Objective-C + + ```objective-c + [scrollView easy_appendView:[[UILabel alloc] init]] + .identifier(@"Label") + .insets(UIEdgeInsetsMake(10, 16, 0, 16)) + .clipsToBounds(YES); + + [scrollView easy_insertView:[[UIImageView alloc] init] after:@"Label"] + .spacing(20) + .clipsToBounds(NO); + + [scrollView easy_appendViewBy:^UIView * _Nonnull{ + return [[UILabel alloc] init]; + }] + .identifier(@"Label") + .insets(UIEdgeInsetsMake(10, 16, 0, 16)); + + [scrollView easy_insertViewBy:^UIView * _Nonnull{ + return [[UIImageView alloc] init]; + } after:@"Label"] + .spacing(20) + .clipsToBounds(NO); + ``` + + + +#### Delete 删除指定视图对象,带动画效果 -```swift -//删除label -self.scrollView.easy.delete(label, completion: nil) -``` +- 使用Swift -```swift -//删除所有子视图 -self.scrollView.easy.deleteAll() -``` + ```swift + //删除label + scrollView.easy.deleteView(label, completion: nil) + //删除image标识的视图 + scrollView.easy.deleteView("image", completion: nil) + //删除所有子视图 + scrollView.easy.deleteAll() + ``` + +- 使用Objective-C + + ```objective-c + //删除label + [scrollView easy_deleteView:label]; + //删除image标识的视图 + [scrollView easy_deleteView:@"image"]; + //删除所有子视图 + [scrollView easy_deleteAll]; + ``` -##### BatchUpdate +#### BatchUpdate -批量更新,带动画效果,更新操作包括append(添加)和delete(删除) +批量更新,带动画效果(可选) ``` //开始更新 @@ -112,121 +271,128 @@ func beginUpdates(option: EasyListUpdateOption = .animatedLayout) func endUpdates(_ completion: (() -> Void)? = nil) ``` +使用Swift + ```swift //执行更新前先调用beginUpdates -self.scrollView.easy.beginUpdates() +scrollView.easy.beginUpdates() -//更新操作:添加view1,删除view2和标识为"view3"的视图 -self.scrollView.easy.append(view1) -self.scrollView.easy.delete(view2) -self.scrollView.easy.delete("view3") +//更新操作:添加view1,在view1后面插入view2,删除view3和标识为"view4"的视图 +scrollView.easy.appendView(view1) +scrollView.easy.insertView(view2, after: view1) +scrollView.easy.deleteView(view3) +scrollView.easy.deleteView("view4") //提交更新,beginUpdates和endUpdates必须成对使用 -self.scrollView.easy.endUpdates { - //完成回调 - print("Update Finish") +scrollView.easy.endUpdates { + //完成回调 + print("Update Finish") } ``` -##### Disposable +使用Objective-C + +```objective-c +//执行更新前先调用beginUpdates +[scrollView easy_beginUpdates]; + +//更新操作:添加view1,在view1后面插入view2,删除view3和标识为"view4"的视图 +[scrollView easy_appendView:view1]; +[scrollView easy_insertView:view2 after:view1]; +[scrollView easy_deleteView:view3]; +[scrollView easy_deleteView:@"view4"]; + +//提交更新,beginUpdates和endUpdates必须成对使用 +[scrollView easy_endUpdatesWithCompletion:^{ + //完成回调 + NSLog(@"Update Finish"); +}]; +``` + + + +#### Disposable 动态回收机制:当视图滚动到屏幕外,将会被销毁回收内存;当重新滚动到屏幕内,将会重新创建并展示,类似于`UITableView`的重用 ```swift //用disposableView包装子视图 -let view = self.scrollView.easy.disposableView { +let view = scrollView.easy.disposableView { let label = UILabel() label.text = "PsyDuck" return label } //添加disposableView包装后的子视图 -self.scrollView.easy.append(view) +scrollView.easy.appendView(view) ``` ```swift //刷新数据 -self.scrollView.easy.reloadDisposableData() +scrollView.easy.reloadDisposableData() ``` ```swift //使用系统或自定义的UIScrollView时,需要在scrollViewDidScroll回调方法中调用triggerDisposable来触发回收机制 //如果使用的是EasyListView对象,则无需调用 func scrollViewDidScroll(_ scrollView: UIScrollView) { - self.scrollView.easy.triggerDisposable() + scrollView.easy.triggerDisposable() } ``` -##### Getter +#### Getter ```swift //获取指定标识的视图对象,包括静态视图和动态视图(处于屏幕外的动态视图可能返回nil) -let label = self.scrollView.easy.getElement(identifier: "myLabel") +let label = scrollView.easy.getElement(identifier: "myLabel") label?.text = "UpdateText" ``` ```swift //获取指定下标的视图对象,仅限于动态视图 -let view = self.scrollView.easy.getDisposableElement(at: 1) +let view = scrollView.easy.getDisposableElement(at: 1) ``` ```swift //获取所有可见的动态子视图 -let views = self.scrollView.easy.visibleDisposableElements +let views = scrollView.easy.visibleDisposableElements ``` -##### Other +#### Other ```swift //设置全局的内边距 -self.scrollView.easy.coordinator.globalEdgeInsets = UIEdgeInsets(top: 20, left: 15, bottom: 20, right: 15) +scrollView.easy.coordinator.globalEdgeInsets = UIEdgeInsets(top: 20, left: 15, bottom: 20, right: 15) ``` ```swift //设置全局的间距 -self.scrollView.easy.coordinator.globalSpacing = 10 +scrollView.easy.coordinator.globalSpacing = 10 ``` ```swift -//设置动画的持续时长 -self.scrollView.easy.coordinator.animationDuration = 1 +//设置全局的超出部分是否裁剪 +scrollView.easy.coordinator.globalClipsToBounds = false ``` -##### For Objective-C - -提供了可供Objective-C调用的方法 - ```swift -//Objective-C请调用easy_前缀的方法 -@objc var easy_coordinator: EasyListCoordinator -@objc func easy_appendView(_ view: ViewOrClosure) -@objc func easy_insertView(_ view: ViewOrClosure, after element: Any) -@objc func easy_insertView(_ view: ViewOrClosure, before element: Any) -@objc func easy_deleteElement(_ element: Any) -@objc func easy_deleteAll() -@objc func easy_beginUpdates() -@objc func easy_endUpdates() -@objc func easy_disposableView(maker: @escaping () -> UIView) -> UIView -@objc func easy_reloadDisposableData() -@objc func easy_triggerDisposable() -@objc func easy_getElement(identifier: String) -> UIView? -@objc func easy_getDisposableElementAtIndex(_ index: Int) -> UIView? -@objc var easy_visibleDisposableElements: [UIView] +//设置动画的持续时长 +scrollView.easy.coordinator.animationDuration = 1 ``` ### 集成 -##### CocoaPods +#### CocoaPods ```ruby pod 'EasyListView' ``` -##### Swift Package Manager +#### Swift Package Manager ```swift dependencies: [ - .package(url: "https://github.com/moliya/EasyListView", from: "1.2.2") + .package(url: "https://github.com/moliya/EasyListView", from: "1.3.0") ] ``` diff --git a/Sources/EasyListExtension.swift b/Sources/EasyListExtension.swift deleted file mode 100644 index fe42eba..0000000 --- a/Sources/EasyListExtension.swift +++ /dev/null @@ -1,823 +0,0 @@ -// -// EasyListExtension.swift -// EasyListViewExample -// -// Created by carefree on 2020/8/8. -// Copyright © 2020 carefree. All rights reserved. -// - -import UIKit -import EasyCompatible - -private var EasyListCoordinatorKey = "EasyListCoordinatorKey" -//添加easy扩展 -extension UIScrollView: EasyCompatible { } - -public extension EasyExtension where Base: UIScrollView { - - internal enum SearchCondition { - case first(UIView, NSLayoutConstraint.Attribute) - case second(UIView, NSLayoutConstraint.Attribute) - case both(UIView?, NSLayoutConstraint.Attribute, - UIView?, NSLayoutConstraint.Attribute) - } - - typealias ViewOrClosure = Any - internal typealias Element = EasyListCoordinator.Element - - // MARK: - Coordinator - var coordinator: EasyListCoordinator { - get { - if let coordinator = objc_getAssociatedObject(self.base, &EasyListCoordinatorKey) as? EasyListCoordinator { - return coordinator - } - let coordinator = EasyListCoordinator(with: self.base) - objc_setAssociatedObject(self.base, &EasyListCoordinatorKey, coordinator, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) - return coordinator - } - set { - objc_setAssociatedObject(self.base, &EasyListCoordinatorKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) - } - } - - // MARK: - Append - /** - 添加一个视图元素 - - * parameter view: 视图或闭包 - */ - func append(_ view: ViewOrClosure) { - var inset = coordinator.globalEdgeInsets - if coordinator.elements.count > 0 { - inset.top = coordinator.globalSpacing - } - append(view, with: inset) - } - - /** - 添加一个视图元素 - - * parameter view: 视图或闭包 - * parameter spacing: 与上一个视图的间距 - */ - func append(_ view: ViewOrClosure, spacing: CGFloat) { - var inset = coordinator.globalEdgeInsets - inset.top = spacing - append(view, with: inset) - } - - /** - 添加一个视图元素 - - * parameter view: 视图或闭包 - * parameter identifier: 视图唯一标识 - * parameter spacing: 与上一个视图的间距 - */ - func append(_ view: ViewOrClosure, for identifier: String = "", spacing: CGFloat = 0) { - var inset = coordinator.globalEdgeInsets - inset.top = spacing - append(view, with: inset, for: identifier) - } - - /** - 添加一个视图元素 - - * parameter view: 视图或闭包 - * parameter insets: 视图自定义的间距 - * parameter identifier: 视图唯一标识 - */ - func append(_ view: ViewOrClosure, with insets: UIEdgeInsets, for identifier: String = "") { - let scrollView = base - - //移除旧的约束 - searchConstraintsIn(scrollView, with: [ - .first(scrollView, .bottom), - .second(scrollView, .bottom) - ]).forEach { $0.isActive = false } - //添加子视图 - var contentView = EasyListContentView() - var isDisposable = false - if let disposableView = view as? EasyListContentView { - //动态元素 - contentView = disposableView - isDisposable = true - } else if let staticView = view as? UIView { - //静态元素 - var view = staticView - if let cell = view as? UITableViewCell { - view = cell.contentView - coordinator.cells[contentView] = cell - } - view.translatesAutoresizingMaskIntoConstraints = false - contentView.addSubview(view) - } else if let closure = view as? () -> UIView { - //闭包 - var view = closure() - if let cell = view as? UITableViewCell { - view = cell.contentView - coordinator.cells[contentView] = cell - } - view.translatesAutoresizingMaskIntoConstraints = false - contentView.addSubview(view) - } - - guard let view = contentView.subviews.first else { return } - - addConstraint(for: contentView, item1: view, attr1: .leading, item2: contentView, attr2: .leading, constant: insets.left) - addConstraint(for: contentView, item1: view, attr1: .trailing, item2: contentView, attr2: .trailing, constant: -insets.right) - addConstraint(for: contentView, item1: view, attr1: .top, item2: contentView, attr2: .top, constant: insets.top) - addConstraint(for: contentView, item1: view, attr1: .bottom, item2: contentView, attr2: .bottom, constant: -insets.bottom) - - contentView.clipsToBounds = true - contentView.translatesAutoresizingMaskIntoConstraints = false - scrollView.addSubview(contentView) - - addConstraint(for: scrollView, item1: scrollView, attr1: .width, item2: contentView, attr2: .width) - addConstraint(for: scrollView, item1: contentView, attr1: .leading, item2: scrollView, attr2: .leading) - addConstraint(for: scrollView, item1: contentView, attr1: .trailing, item2: scrollView, attr2: .trailing) - addConstraint(for: scrollView, item1: contentView, attr1: .bottom, item2: scrollView, attr2: .bottom) - if let lastView = coordinator.elements.last?.view { - addConstraint(for: scrollView, item1: contentView, attr1: .top, item2: lastView, attr2: .bottom) - } else { - addConstraint(for: scrollView, item1: contentView, attr1: .top, item2: scrollView, attr2: .top) - } - - var element = Element(view: contentView, insets: insets, identifier: identifier) - coordinator.elements.append(element) - if isDisposable { - coordinator.disposableElements.append(Element(view: contentView, insets: insets, identifier: identifier)) - } - - if coordinator.onBatchUpdate { - element.inserting = true - } - } - - // MARK: - Insert - /** - 插入一个视图元素 - - * parameter view: 视图或闭包 - * parameter element: 前一个视图元素,可以是UIView,也可以是视图唯一标识 - * parameter insets: 视图自定义的间距 - * parameter identifier: 视图唯一标识 - * parameter completion: 插入完成回调 - */ - func insert(_ view: ViewOrClosure, after element: Any, with insets: UIEdgeInsets = .zero, for identifier: String = "", completion: (() -> Void)? = nil) { - let scrollView = base - let elements = coordinator.elements - - var relateView: UIView? - if let string = element as? String { - relateView = elements.first { $0.identifier == string }?.view - } - if let cell = element as? UITableViewCell { - relateView = coordinator.cells.first { $0.value == cell }?.key - } else if let view = element as? UIView { - if view == scrollView { - relateView = view - } else { - relateView = elements.first { $0.view == view.superview }?.view - } - } - assert(relateView != nil, "invalid element") - - //查找前后视图及下标 - var previousView: UIView? - var nextView: UIView = scrollView - var flag = false - var index = -1 - if relateView == scrollView { - previousView = scrollView - flag = true - index = 0 - } - for i in 0 ..< elements.count { - if elements[i].view == relateView { - previousView = elements[i].view - flag = true - index = i + 1 - continue - } else if flag { - nextView = elements[i].view - break - } - } - - insert(view, previousView: previousView, nextView: nextView, index: index, with: insets, for: identifier, completion: completion) - } - - /** - 插入一个视图元素 - - * parameter view: 视图或闭包 - * parameter element: 后一个视图元素,可以是UIView,也可以是视图唯一标识 - * parameter insets: 视图自定义的间距 - * parameter identifier: 视图唯一标识 - * parameter completion: 插入完成回调 - */ - func insert(_ view: ViewOrClosure, before element: Any, with insets: UIEdgeInsets = .zero, for identifier: String = "", completion: (() -> Void)? = nil) { - let scrollView = base - let elements = coordinator.elements - - var relateView: UIView? - if let string = element as? String { - relateView = elements.first { $0.identifier == string }?.view - } - if let cell = element as? UITableViewCell { - relateView = coordinator.cells.first { $0.value == cell }?.key - } else if let view = element as? UIView { - if view == scrollView { - relateView = view - } else { - relateView = elements.first { $0.view == view.superview }?.view - } - } - assert(relateView != nil, "invalid element") - - //查找前后视图及下标 - var previousView: UIView = scrollView - var nextView: UIView? - var flag = false - var index = -1 - if relateView == scrollView { - nextView = scrollView - flag = true - index = elements.count - } - for i in (0 ..< elements.count).reversed() { - if elements[i].view == relateView { - nextView = elements[i].view - flag = true - index = i - continue - } else if flag { - previousView = elements[i].view - break - } - } - - insert(view, previousView: previousView, nextView: nextView, index: index, with: insets, for: identifier, completion: completion) - } - - /** - 插入一个视图元素 - - * parameter view: 视图或闭包 - * parameter previousView: 前一个视图元素 - * parameter nextView: 后一个视图元素 - * parameter index: 插入的下标 - * parameter insets: 视图自定义的间距 - * parameter identifier: 视图唯一标识 - * parameter completion: 插入完成回调 - */ - internal func insert(_ view: ViewOrClosure, previousView: UIView?, nextView: UIView?, index: Int, with insets: UIEdgeInsets, for identifier: String, completion: (() -> Void)?) { - let scrollView = base - - //移除旧的约束 - searchConstraintsIn(scrollView, with: [ - .both(previousView, .top, nextView, .top), - .both(previousView, .top, nextView, .bottom), - .both(previousView, .bottom, nextView, .top), - .both(previousView, .bottom, nextView, .bottom), - .both(nextView, .top, previousView, .top), - .both(nextView, .top, previousView, .bottom), - .both(nextView, .bottom, previousView, .top), - .both(nextView, .bottom, previousView, .bottom) - ]).forEach { $0.isActive = false } - //插入子视图 - var contentView = EasyListContentView() - var isDisposable = false - if let disposableView = view as? EasyListContentView { - //动态元素 - contentView = disposableView - isDisposable = true - } else if let staticView = view as? UIView { - //静态元素 - var view = staticView - if let cell = view as? UITableViewCell { - view = cell.contentView - coordinator.cells[contentView] = cell - } - view.translatesAutoresizingMaskIntoConstraints = false - contentView.addSubview(view) - } else if let closure = view as? () -> UIView { - //闭包 - var view = closure() - if let cell = view as? UITableViewCell { - view = cell.contentView - coordinator.cells[contentView] = cell - } - view.translatesAutoresizingMaskIntoConstraints = false - contentView.addSubview(view) - } - - guard let view = contentView.subviews.first else { return } - - addConstraint(for: contentView, item1: view, attr1: .leading, item2: contentView, attr2: .leading, constant: insets.left) - addConstraint(for: contentView, item1: view, attr1: .trailing, item2: contentView, attr2: .trailing, constant: -insets.right) - addConstraint(for: contentView, item1: view, attr1: .top, item2: contentView, attr2: .top, constant: insets.top) - addConstraint(for: contentView, item1: view, attr1: .bottom, item2: contentView, attr2: .bottom, constant: -insets.bottom) - - contentView.clipsToBounds = true - contentView.translatesAutoresizingMaskIntoConstraints = false - scrollView.addSubview(contentView) - - addConstraint(for: scrollView, item1: scrollView, attr1: .width, item2: contentView, attr2: .width) - addConstraint(for: scrollView, item1: contentView, attr1: .leading, item2: scrollView, attr2: .leading) - addConstraint(for: scrollView, item1: contentView, attr1: .trailing, item2: scrollView, attr2: .trailing) - if previousView == scrollView { - addConstraint(for: scrollView, item1: contentView, attr1: .top, item2: previousView, attr2: .top) - } else { - addConstraint(for: scrollView, item1: contentView, attr1: .top, item2: previousView, attr2: .bottom) - } - if nextView == scrollView { - addConstraint(for: scrollView, item1: contentView, attr1: .bottom, item2: nextView, attr2: .bottom) - } else { - addConstraint(for: scrollView, item1: nextView!, attr1: .top, item2: contentView, attr2: .bottom) - } - - var element = Element(view: contentView, insets: insets, identifier: identifier) - element.inserting = true - coordinator.elements.insert(element, at: index) - if isDisposable { - var disposableIndex = 0 - for tmp in coordinator.disposableElements { - for i in 0 ..< index { - if tmp.view == coordinator.elements[i].view { - disposableIndex += 1 - } - } - } - coordinator.disposableElements.insert(Element(view: contentView, insets: insets, identifier: identifier), at: disposableIndex) - } - - if coordinator.onBatchUpdate { - completion?() - return - } - - animateInsertion(completion: { - self.reloadDisposableIfNeed() - completion?() - }, duration: coordinator.animationDuration) - } - - // MARK: - Delete - /** - 删除一个视图元素 - - * parameter element: 要删除的视图,可以是UIView,也可以是视图的唯一标识 - * parameter completion: 删除完成后的回调 - */ - func delete(_ element: Any, completion: (() -> Void)? = nil) { - let elements = coordinator.elements - - var targetView: UIView? - if let string = element as? String { - targetView = elements.first { $0.identifier == string }?.view - } - if let cell = element as? UITableViewCell { - targetView = coordinator.cells.first { $0.value == cell }?.key - } else if let view = element as? UIView { - targetView = elements.first { $0.view == view.superview }?.view - } - assert(targetView != nil, "invalid element") - - coordinator.elements = coordinator.elements.map { - var tmp = $0 - if targetView == tmp.view && !tmp.deleting { - tmp.deleting = true - } - return tmp - } - - if coordinator.onBatchUpdate { - completion?() - return - } - - animateDeletion(completion: { - self.reloadDisposableIfNeed() - completion?() - }, duration: coordinator.animationDuration) - } - - /** - 删除所有视图元素 - - */ - func deleteAll() { - coordinator.elements.forEach { - $0.view.removeFromSuperview() - } - coordinator.elements.removeAll() - coordinator.disposableElements.removeAll() - } - - // MARK: - BatchUpdate - /** - 开始批量更新操作 - - * parameter option: 更新方式 - * Note: 需和endUpdates成对使用。 - */ - func beginUpdates(option: EasyListUpdateOption = .animatedLayout) { - coordinator.onBatchUpdate = true - coordinator.batchUpdateOption = option - } - - /** - 完成批量更新操作 - - * parameter completion: 更新完成后的回调 - */ - func endUpdates(_ completion: (() -> Void)? = nil) { - coordinator.onBatchUpdate = false - - let insertingCount = coordinator.elements.filter { $0.inserting }.count - let deletingCount = coordinator.elements.filter { $0.deleting }.count - - //不执行layout - if coordinator.batchUpdateOption == .noLayout { - //清理标记 - if insertingCount > 0 { - lastStepForInserting() - } - if deletingCount > 0 { - lastStepForDeleting() - } - //完成回调 - completion?() - return - } - - //无动画的layout - if coordinator.batchUpdateOption == .onlyLayout { - //更新约束 - resetConstraintsForDeleting() - base.layoutIfNeeded() - self.reloadDisposableIfNeed() - //清理标记 - if insertingCount > 0 { - lastStepForInserting() - } - if deletingCount > 0 { - lastStepForDeleting() - } - //完成回调 - completion?() - return - } - - //带动画的layout - let duration = coordinator.animationDuration - if insertingCount > 0 && deletingCount > 0 { - //先执行插入动画 - self.animateInsertion(completion: { - //再执行删除动画 - self.animateDeletion(completion: completion, duration: duration / 2) - }, duration: duration / 2) - } else if insertingCount > 0 { - //执行插入动画 - self.animateInsertion(completion: completion, duration: duration) - } else if deletingCount > 0 { - //执行删除动画 - self.animateDeletion(completion: completion, duration: duration) - } else { - //兜底代码 - self.reloadDisposableIfNeed() - completion?() - } - } - - // MARK: - Disposable - /** - 生成自释放元素 - - * parameter maker: 闭包 - - * returns: 生成的视图 - */ - func disposableView(with maker: @escaping () -> UIView) -> UIView { - let contentView = EasyListContentView() - var view = maker() - if let cell = view as? UITableViewCell { - view = cell.contentView - coordinator.cells[contentView] = cell - } - view.translatesAutoresizingMaskIntoConstraints = false - contentView.addSubview(view) - contentView.disposableMaker = maker - - return contentView - } - - /** - 刷新数据 - - */ - func reloadDisposableData() { - coordinator.disposableElements.forEach { - $0.view.subviews.first?.removeFromSuperview() - } - reloadDisposableIfNeed() - } - - /** - 触发自释放机制 - - */ - func triggerDisposable() { - let scrollView = base - - let offset = scrollView.contentOffset.y - let range = scrollView.frame.height - let minY = offset - range - let maxY = offset + range + range - - coordinator.disposableElements.forEach { element in - let contentView = element.view - let frame = contentView.frame - guard let maker = contentView.disposableMaker else { return } - - if frame.maxY >= minY && frame.minY <= maxY { - //在可视范围内 - if contentView.subviews.count == 0 { - //恢复子视图 - var view = maker() - if let cell = view as? UITableViewCell { - view = cell.contentView - coordinator.cells[contentView] = cell - } - view.translatesAutoresizingMaskIntoConstraints = false - contentView.addSubview(view) - addConstraint(for: contentView, item1: view, attr1: .leading, item2: contentView, attr2: .leading, constant: element.insets.left) - addConstraint(for: contentView, item1: view, attr1: .trailing, item2: contentView, attr2: .trailing, constant: -element.insets.right) - addConstraint(for: contentView, item1: view, attr1: .top, item2: contentView, attr2: .top, constant: element.insets.top) - addConstraint(for: contentView, item1: view, attr1: .bottom, item2: contentView, attr2: .bottom, constant: -element.insets.bottom) - //删除height约束 - contentView.constraints.first { $0.firstAttribute == .height }?.isActive = false - } - } else { - //不在可视范围内 - if contentView.subviews.count > 0 { - //移除子视图,回收内存 - addConstraint(for: contentView, item1: contentView, attr1: .height, item2: nil, attr2: .notAnAttribute, constant: frame.height) - coordinator.cells.removeValue(forKey: contentView) - contentView.subviews.forEach { $0.removeFromSuperview() } - } - } - } - } - - // MARK: - Getter - /** - 获取视图元素 - - * parameter identifier: 视图唯一标识 - - * returns: 找到的视图 - */ - func getElement(identifier: String) -> UIView? { - let getView = coordinator.elements.first { $0.identifier == identifier }?.view - guard let contentView = getView else { - return nil - } - if let cell = coordinator.cells[contentView] { - return cell - } - return contentView.subviews.first - } - - /** - 获取指定下标的自释放元素 - - * parameter index: 下标 - - * returns: 找到的视图 - */ - func getDisposableElement(at index: Int) -> UIView? { - if index >= coordinator.disposableElements.count { - return nil - } - let contentView = coordinator.disposableElements[index].view - if let cell = coordinator.cells[contentView] { - return cell - } - return contentView.subviews.first - } - - /** - 获取所有可视的自释放元素 - - * returns: 找到的视图集合 - */ - var visibleDisposableElements: [UIView] { - return coordinator.disposableElements.compactMap { - let contentView = $0.view - if let cell = coordinator.cells[contentView] { - return cell - } - return contentView.subviews.first - } - } - - // MARK: - Private - //插入动画 - private func animateInsertion(completion: (() -> Void)? = nil, duration: TimeInterval) { - let scrollView = base - let elements = coordinator.elements - - //替换bottom约束为高度约束 - let insertingViews = elements.filter { $0.inserting }.map { $0.view } - var heightConstraints = [(constraint: NSLayoutConstraint, subview: UIView, offset: CGFloat)]() - var bottomConstraints = [NSLayoutConstraint]() - for view in insertingViews { - var offset: CGFloat = 0 - searchConstraintsIn(view, with: [ - .first(view, .top), - .second(view, .top), - .first(view, .bottom), - .second(view, .bottom) - ]).forEach { - if $0.firstAttribute == .top || $0.secondAttribute == .top { - offset += $0.constant - } else { - bottomConstraints.append($0) - $0.isActive = false - offset -= $0.constant - } - } - let constraint = addConstraint(for: view, item1: view, attr1: .height, item2: nil, attr2: .notAnAttribute) - heightConstraints.append((constraint, view.subviews.first!, offset)) - } - - scrollView.layoutIfNeeded() - //更新高度约束 - heightConstraints.forEach { - $0.constraint.constant = $0.subview.frame.size.height + $0.offset - } - UIView.animate(withDuration: duration, animations: { - scrollView.layoutIfNeeded() - }) { _ in - self.reloadDisposableIfNeed() - //删除height约束 - heightConstraints.forEach { - $0.constraint.isActive = false - } - //恢复bottom约束 - bottomConstraints.forEach { - $0.isActive = true - } - self.lastStepForInserting() - completion?() - } - } - - // 删除动画 - private func animateDeletion(completion: (() -> Void)? = nil, duration: TimeInterval) { - let scrollView = base - let elements = coordinator.elements - - //替换bottom约束为高度约束 - let deletingViews = elements.filter { $0.deleting }.map { $0.view } - if deletingViews.count == 0 { - completion?() - return - } - for view in deletingViews { - let height = view.frame.size.height - view.constraints.forEach { - if let item = $0.firstItem as? UIView, item == view && $0.firstAttribute == .bottom { - $0.isActive = false - } - if let item = $0.secondItem as? UIView, item == view && $0.secondAttribute == .bottom { - $0.isActive = false - } - } - let heightConstraint = addConstraint(for: view, item1: view, attr1: .height, item2: nil, attr2: .notAnAttribute, constant: height) - view.layoutIfNeeded() - - heightConstraint.constant = 0 - } - - //更新布局 - UIView.animate(withDuration: duration * 3 / 4, animations: { - scrollView.layoutIfNeeded() - }) { _ in - //更新约束 - self.resetConstraintsForDeleting() - UIView.animate(withDuration: duration / 4, animations: { - scrollView.layoutIfNeeded() - }) { _ in - //完成后移除相关元素 - self.lastStepForDeleting() - completion?() - } - } - } - - //刷新 - private func reloadDisposableIfNeed() { - triggerDisposable() - } - - //查找符合条件的约束 - private func searchConstraintsIn(_ view: UIView, with conditions: [SearchCondition]) -> [NSLayoutConstraint] { - var results = [NSLayoutConstraint]() - for constraint in view.constraints { - for condition in conditions { - switch condition { - case .first(let firstItem, let firstAttribute): - //匹配first - guard let item = constraint.firstItem as? UIView else { break } - if item == firstItem && constraint.firstAttribute == firstAttribute { - results.append(constraint) - } - case .second(let secondItem, let secondAttribute): - //匹配second - guard let item = constraint.secondItem as? UIView else { break } - if item == secondItem && constraint.secondAttribute == secondAttribute { - results.append(constraint) - } - case .both(let firstItem, let firstAttribute, let secondItem, let secondAttribute): - //匹配全部 - guard let first = constraint.firstItem as? UIView, let second = constraint.secondItem as? UIView else { - break - } - if first == firstItem && - second == secondItem && - constraint.firstAttribute == firstAttribute && - constraint.secondAttribute == secondAttribute { - results.append(constraint) - } - } - } - } - return results - } - - //针对删除的元素重新构建约束 - private func resetConstraintsForDeleting() { - let scrollView = base - - var list = [(UIView, UIView)]() - var previousView: UIView = scrollView - var nextView: UIView? - var flag = false - for element in coordinator.elements { - if element.deleting { - flag = true - continue - } - if flag { - nextView = element.view - } else { - previousView = element.view - } - if let view = nextView { - list.append((previousView, view)) - - previousView = element.view - nextView = nil - flag = false - } - } - if flag { - list.append((previousView, scrollView)) - } - for (previousView, nextView) in list { - if previousView == nextView { - continue - } - if previousView == scrollView { - addConstraint(for: scrollView, item1: nextView, attr1: .top, item2: previousView, attr2: .top) - } else if nextView == scrollView { - addConstraint(for: scrollView, item1: nextView, attr1: .bottom, item2: previousView, attr2: .bottom) - } else { - addConstraint(for: scrollView, item1: nextView, attr1: .top, item2: previousView, attr2: .bottom) - } - } - } - - private func lastStepForDeleting() { - coordinator.elements.filter { - return $0.deleting - }.map { - return $0.view - }.forEach { - $0.removeFromSuperview() - self.coordinator.cells.removeValue(forKey: $0) - } - coordinator.elements.removeAll { $0.deleting } - } - - private func lastStepForInserting() { - coordinator.elements = coordinator.elements.map { - var tmp = $0 - tmp.inserting = false - return tmp - } - } -} diff --git a/Sources/EasyListObjC.swift b/Sources/EasyListObjC.swift deleted file mode 100644 index eb88f9e..0000000 --- a/Sources/EasyListObjC.swift +++ /dev/null @@ -1,176 +0,0 @@ -// -// EasyListObjC.swift -// EasyListViewExample -// -// Created by carefree on 2020/8/18. -// Copyright © 2020 carefree. All rights reserved. -// - -import UIKit - -public extension UIScrollView { - - // MARK: - Coordinator - @objc var easy_coordinator: EasyListCoordinator { - get { - return easy.coordinator - } - set { - easy.coordinator = newValue - } - } - - // MARK: - Append - @objc func easy_appendView(_ view: UIView) { - easy.append(view) - } - - @objc func easy_appendViewBy(_ block: () -> UIView) { - easy.append(block()) - } - - @objc func easy_appendView(_ view: UIView, spacing: CGFloat) { - easy.append(view, spacing: spacing) - } - - @objc func easy_appendViewBy(_ block: () -> UIView, spacing: CGFloat) { - easy.append(block(), spacing: spacing) - } - - @objc func easy_appendView(_ view: UIView, forIdentifier identifier: String, spacing: CGFloat) { - easy.append(view, for: identifier, spacing: spacing) - } - - @objc func easy_appendViewBy(_ block: () -> UIView, forIdentifier identifier: String, spacing: CGFloat) { - easy.append(block(), for: identifier, spacing: spacing) - } - - @objc func easy_appendView(_ view: UIView, forIdentifier identifier: String, withInsets insets: UIEdgeInsets) { - easy.append(view, with: insets, for: identifier) - } - - @objc func easy_appendViewBy(_ block: () -> UIView, forIdentifier identifier: String, withInsets insets: UIEdgeInsets) { - easy.append(block(), with: insets, for: identifier) - } - - // MARK: - Insert - @objc func easy_insertView(_ view: UIView, after element: Any) { - easy.insert(view, after: element) - } - - @objc func easy_insertViewBy(_ block: () -> UIView, after element: Any) { - easy.insert(block(), after: element) - } - - @objc func easy_insertView(_ view: UIView, after element: Any, withInsets insets: UIEdgeInsets) { - easy.insert(view, after: element, with: insets) - } - - @objc func easy_insertViewBy(_ block: () -> UIView, after element: Any, withInsets insets: UIEdgeInsets) { - easy.insert(block(), after: element, with: insets) - } - - @objc func easy_insertView(_ view: UIView, after element: Any, withInsets insets: UIEdgeInsets, forIdentifier identifier: String) { - easy.insert(view, after: element, with: insets, for: identifier) - } - - @objc func easy_insertViewBy(_ block: () -> UIView, after element: Any, withInsets insets: UIEdgeInsets, forIdentifier identifier: String) { - easy.insert(block(), after: element, with: insets, for: identifier) - } - - @objc func easy_insertView(_ view: UIView, after element: Any, withInsets insets: UIEdgeInsets, forIdentifier identifier: String, completion: (() -> Void)?) { - easy.insert(view, after: element, with: insets, for: identifier, completion: completion) - } - - @objc func easy_insertViewBy(_ block: () -> UIView, after element: Any, withInsets insets: UIEdgeInsets, forIdentifier identifier: String, completion: (() -> Void)?) { - easy.insert(block(), after: element, with: insets, for: identifier, completion: completion) - } - - @objc func easy_insertView(_ view: UIView, before element: Any) { - easy.insert(view, before: element) - } - - @objc func easy_insertViewBy(_ block: () -> UIView, before element: Any) { - easy.insert(block(), before: element) - } - - @objc func easy_insertView(_ view: UIView, before element: Any, withInsets insets: UIEdgeInsets) { - easy.insert(view, before: element, with: insets) - } - - @objc func easy_insertViewBy(_ block: () -> UIView, before element: Any, withInsets insets: UIEdgeInsets) { - easy.insert(block(), before: element, with: insets) - } - - @objc func easy_insertView(_ view: UIView, before element: Any, withInsets insets: UIEdgeInsets, forIdentifier identifier: String) { - easy.insert(view, before: element, with: insets, for: identifier) - } - - @objc func easy_insertViewBy(_ block: () -> UIView, before element: Any, withInsets insets: UIEdgeInsets, forIdentifier identifier: String) { - easy.insert(block(), before: element, with: insets, for: identifier) - } - - @objc func easy_insertView(_ view: UIView, before element: Any, withInsets insets: UIEdgeInsets, forIdentifier identifier: String, completion: (() -> Void)?) { - easy.insert(view, before: element, with: insets, for: identifier, completion: completion) - } - - @objc func easy_insertViewBy(_ block: () -> UIView, before element: Any, withInsets insets: UIEdgeInsets, forIdentifier identifier: String, completion: (() -> Void)?) { - easy.insert(block(), before: element, with: insets, for: identifier, completion: completion) - } - - // MARK: - Delete - @objc func easy_deleteElement(_ element: Any) { - easy.delete(element) - } - - @objc func easy_deleteElement(_ element: Any, completion: (() -> Void)?) { - easy.delete(element, completion: completion) - } - - @objc func easy_deleteAll() { - easy.deleteAll() - } - - // MARK: - BatchUpdate - @objc func easy_beginUpdates() { - easy.beginUpdates() - } - - @objc func easy_beginUpdates(option: EasyListUpdateOption) { - easy.beginUpdates(option: option) - } - - @objc func easy_endUpdates() { - easy.endUpdates() - } - - @objc func easy_endUpdates(completion: (() -> Void)?) { - easy.endUpdates(completion) - } - - // MARK: - Disposable - @objc func easy_disposableView(maker: @escaping () -> UIView) -> UIView { - return easy.disposableView(with: maker) - } - - @objc func easy_reloadDisposableData() { - easy.reloadDisposableData() - } - - @objc func easy_triggerDisposable() { - easy.triggerDisposable() - } - - // MARK: - Getter - @objc func easy_getElement(identifier: String) -> AnyObject? { - return easy.getElement(identifier: identifier) - } - - @objc func easy_getDisposableElementAtIndex(_ index: Int) -> AnyObject? { - return easy.getDisposableElement(at: index) - } - - @objc var easy_visibleDisposableElements: [AnyObject] { - return easy.visibleDisposableElements - } -} diff --git a/Sources/ObjC/EasyListObjC.swift b/Sources/ObjC/EasyListObjC.swift new file mode 100644 index 0000000..cdf73d2 --- /dev/null +++ b/Sources/ObjC/EasyListObjC.swift @@ -0,0 +1,298 @@ +// +// EasyListObjC.swift +// EasyListViewExample +// +// Created by carefree on 2020/8/18. +// Copyright © 2020 carefree. All rights reserved. +// + +import UIKit + +@objc open class EasyListObjCAttributes: NSObject { + fileprivate var attributes: EasyListAttributes + + init(_ attributes: EasyListAttributes) { + self.attributes = attributes + super.init() + } +} + +@objc public extension EasyListObjCAttributes { + /** + 设置唯一标识 + + * parameter identifier: 标识字符串 + + * returns: 自定义配置项 + */ + var identifier: (String) -> EasyListObjCAttributes { + return { identifier in + self.attributes.identifier(identifier) + return self + } + } + + /** + 设置内间距 + + * parameter insets: 内间距 + + * returns: 自定义配置项 + */ + var insets: (UIEdgeInsets) -> EasyListObjCAttributes { + return { insets in + self.attributes.insets(insets) + return self + } + } + + /** + 设置与上一元素的间距 + + * parameter spacing: 间距 + + * returns: 自定义配置项 + */ + var spacing: (CGFloat) -> EasyListObjCAttributes { + return { spacing in + self.attributes.spacing(spacing) + return self + } + } + + /** + 设置超出部分是否裁剪 + + * parameter clipsToBounds: 是否裁剪 + + * returns: 自定义配置项 + */ + var clipsToBounds: (Bool) -> EasyListObjCAttributes { + return { clipsToBounds in + self.attributes.clipsToBounds(clipsToBounds) + return self + } + } +} + +@available(*, unavailable) +@objc public extension UIScrollView { + // MARK: - Coordinator + var easy_coordinator: EasyListCoordinator { + get { + return easy.coordinator + } + set { + easy.coordinator = newValue + } + } + + // MARK: - Append + /** + 添加一个视图元素 + + * parameter view: 视图 + + * returns: 自定义配置项 + */ + @discardableResult + func easy_appendView(_ view: UIView) -> EasyListObjCAttributes { + let attributes = easy.appendView(view) + return EasyListObjCAttributes(attributes) + } + + /** + 添加一个视图元素 + + * parameter block: 视图block + + * returns: 自定义配置项 + */ + @discardableResult + func easy_appendViewBy(_ block: () -> UIView) -> EasyListObjCAttributes { + let attributes = easy.appendView(block) + return EasyListObjCAttributes(attributes) + } + + // MARK: - Insert + /** + 在目标之后插入一个视图元素 + + * parameter view: 视图 + * parameter element: 前一个视图元素,可以是UIView,也可以是视图唯一标识 + + * returns: 自定义配置项 + */ + @discardableResult + func easy_insertView(_ view: UIView, after element: Any) -> EasyListObjCAttributes { + let attributes = easy.insertView(view, after: element) + return EasyListObjCAttributes(attributes) + } + + /** + 在目标之后插入一个视图元素 + + * parameter block: 视图block + * parameter element: 前一个视图元素,可以是UIView,也可以是视图唯一标识 + + * returns: 自定义配置项 + */ + @discardableResult + func easy_insertViewBy(_ block: () -> UIView, after element: Any) -> EasyListObjCAttributes { + let attributes = easy.insertView(block, after: element) + return EasyListObjCAttributes(attributes) + } + + /** + 在目标之前插入一个视图元素 + + * parameter view: 视图 + * parameter element: 后一个视图元素,可以是UIView,也可以是视图唯一标识 + + * returns: 自定义配置项 + */ + @discardableResult + func easy_insertView(_ view: UIView, before element: Any) -> EasyListObjCAttributes { + let attributes = easy.insertView(view, before: element) + return EasyListObjCAttributes(attributes) + } + + /** + 在目标之前插入一个视图元素 + + * parameter block: 视图block + * parameter element: 后一个视图元素,可以是UIView,也可以是视图唯一标识 + + * returns: 自定义配置项 + */ + @discardableResult + func easy_insertViewBy(_ block: () -> UIView, before element: Any) -> EasyListObjCAttributes { + let attributes = easy.insertView(block, before: element) + return EasyListObjCAttributes(attributes) + } + + // MARK: - Delete + /** + 删除一个视图元素 + + * parameter view: 要删除的视图,可以是UIView,也可以是视图的唯一标识 + */ + func easy_deleteView(_ view: Any) { + easy.deleteView(view) + } + + /** + 删除一个视图元素 + + * parameter view: 要删除的视图,可以是UIView,也可以是视图的唯一标识 + * parameter completion: 删除完成后的回调 + */ + func easy_deleteView(_ view: Any, completion: (() -> Void)?) { + easy.deleteView(view, completion: completion) + } + + /** + 删除所有视图元素 + + */ + func easy_deleteAll() { + easy.deleteAll() + } + + // MARK: - BatchUpdate + /** + 开始批量更新操作 + + * Note: 需和endUpdates成对使用。 + */ + func easy_beginUpdates() { + easy.beginUpdates() + } + + /** + 开始批量更新操作 + + * parameter option: 更新方式 + * Note: 需和endUpdates成对使用。 + */ + func easy_beginUpdates(option: EasyListUpdateOption) { + easy.beginUpdates(option: option) + } + + /** + 完成批量更新操作 + + */ + func easy_endUpdates() { + easy.endUpdates() + } + + /** + 完成批量更新操作 + + * parameter completion: 更新完成后的回调 + */ + func easy_endUpdates(completion: (() -> Void)?) { + easy.endUpdates(completion) + } + + // MARK: - Disposable + /** + 生成自释放元素 + + * parameter maker: 闭包 + + * returns: 生成的视图 + */ + func easy_disposableView(maker: @escaping () -> UIView) -> UIView { + return easy.disposableView(with: maker) + } + + /** + 刷新数据 + + */ + func easy_reloadDisposableData() { + easy.reloadDisposableData() + } + + /** + 触发自释放机制 + + */ + func easy_triggerDisposable() { + easy.triggerDisposable() + } + + // MARK: - Getter + /** + 获取视图元素 + + * parameter identifier: 视图唯一标识 + + * returns: 找到的视图 + */ + func easy_getElement(identifier: String) -> AnyObject? { + return easy.getElement(identifier: identifier) + } + + /** + 获取指定下标的自释放元素 + + * parameter index: 下标 + + * returns: 找到的视图 + */ + func easy_getDisposableElementAtIndex(_ index: Int) -> AnyObject? { + return easy.getDisposableElement(at: index) + } + + /** + 获取所有可视的自释放元素 + + * returns: 找到的视图集合 + */ + var easy_visibleDisposableElements: [AnyObject] { + return easy.visibleDisposableElements + } +} diff --git a/Sources/ObjC/EasyListObjCDeprecated.swift b/Sources/ObjC/EasyListObjCDeprecated.swift new file mode 100644 index 0000000..dd47256 --- /dev/null +++ b/Sources/ObjC/EasyListObjCDeprecated.swift @@ -0,0 +1,115 @@ +// +// EasyListObjCDeprecated.swift +// EasyListViewExample +// +// Created by carefree on 2022/10/8. +// Copyright © 2022 carefree. All rights reserved. +// + +import UIKit + +@available(*, unavailable) +@objc public extension UIScrollView { + // MARK: - Append + @available(*, deprecated, message: "Please use easy_appendView: instead.") + func easy_appendView(_ view: UIView, spacing: CGFloat) { + easy.append(view, spacing: spacing) + } + + @available(*, deprecated, message: "Please use easy_appendViewBy: instead.") + func easy_appendViewBy(_ block: () -> UIView, spacing: CGFloat) { + easy.append(block(), spacing: spacing) + } + + @available(*, deprecated, message: "Please use easy_appendView: instead.") + func easy_appendView(_ view: UIView, forIdentifier identifier: String, spacing: CGFloat) { + easy.append(view, for: identifier, spacing: spacing) + } + + @available(*, deprecated, message: "Please use easy_appendViewBy: instead.") + func easy_appendViewBy(_ block: () -> UIView, forIdentifier identifier: String, spacing: CGFloat) { + easy.append(block(), for: identifier, spacing: spacing) + } + + @available(*, deprecated, message: "Please use easy_appendView: instead.") + func easy_appendView(_ view: UIView, forIdentifier identifier: String, withInsets insets: UIEdgeInsets) { + easy.append(view, with: insets, for: identifier) + } + + @available(*, deprecated, message: "Please use easy_appendViewBy: instead.") + func easy_appendViewBy(_ block: () -> UIView, forIdentifier identifier: String, withInsets insets: UIEdgeInsets) { + easy.append(block(), with: insets, for: identifier) + } + + // MARK: - Insert + @available(*, deprecated, message: "Please use easy_insertView:after: instead.") + func easy_insertView(_ view: UIView, after element: Any, withInsets insets: UIEdgeInsets) { + easy.insert(view, after: element, with: insets) + } + + @available(*, deprecated, message: "Please use easy_insertView:after: instead.") + func easy_insertViewBy(_ block: () -> UIView, after element: Any, withInsets insets: UIEdgeInsets) { + easy.insert(block(), after: element, with: insets) + } + + @available(*, deprecated, message: "Please use easy_insertView:after: instead.") + func easy_insertView(_ view: UIView, after element: Any, withInsets insets: UIEdgeInsets, forIdentifier identifier: String) { + easy.insert(view, after: element, with: insets, for: identifier) + } + + @available(*, deprecated, message: "Please use easy_insertView:after: instead.") + func easy_insertViewBy(_ block: () -> UIView, after element: Any, withInsets insets: UIEdgeInsets, forIdentifier identifier: String) { + easy.insert(block(), after: element, with: insets, for: identifier) + } + + @available(*, deprecated, message: "Please use easy_insertView:after: instead.") + func easy_insertView(_ view: UIView, after element: Any, withInsets insets: UIEdgeInsets, forIdentifier identifier: String, completion: (() -> Void)?) { + easy.insert(view, after: element, with: insets, for: identifier, completion: completion) + } + + @available(*, deprecated, message: "Please use easy_insertView:after: instead.") + func easy_insertViewBy(_ block: () -> UIView, after element: Any, withInsets insets: UIEdgeInsets, forIdentifier identifier: String, completion: (() -> Void)?) { + easy.insert(block(), after: element, with: insets, for: identifier, completion: completion) + } + + @available(*, deprecated, message: "Please use easy_insertView:before: instead.") + func easy_insertView(_ view: UIView, before element: Any, withInsets insets: UIEdgeInsets) { + easy.insert(view, before: element, with: insets) + } + + @available(*, deprecated, message: "Please use easy_insertView:before: instead.") + func easy_insertViewBy(_ block: () -> UIView, before element: Any, withInsets insets: UIEdgeInsets) { + easy.insert(block(), before: element, with: insets) + } + + @available(*, deprecated, message: "Please use easy_insertView:before: instead.") + func easy_insertView(_ view: UIView, before element: Any, withInsets insets: UIEdgeInsets, forIdentifier identifier: String) { + easy.insert(view, before: element, with: insets, for: identifier) + } + + @available(*, deprecated, message: "Please use easy_insertView:before: instead.") + func easy_insertViewBy(_ block: () -> UIView, before element: Any, withInsets insets: UIEdgeInsets, forIdentifier identifier: String) { + easy.insert(block(), before: element, with: insets, for: identifier) + } + + @available(*, deprecated, message: "Please use easy_insertView:before: instead.") + func easy_insertView(_ view: UIView, before element: Any, withInsets insets: UIEdgeInsets, forIdentifier identifier: String, completion: (() -> Void)?) { + easy.insert(view, before: element, with: insets, for: identifier, completion: completion) + } + + @available(*, deprecated, message: "Please use easy_insertView:before: instead.") + func easy_insertViewBy(_ block: () -> UIView, before element: Any, withInsets insets: UIEdgeInsets, forIdentifier identifier: String, completion: (() -> Void)?) { + easy.insert(block(), before: element, with: insets, for: identifier, completion: completion) + } + + // MARK: - Delete + @available(*, deprecated, message: "Please use easy_deleteView: instead.") + func easy_deleteElement(_ element: Any) { + easy.delete(element) + } + + @available(*, deprecated, message: "Please use easy_deleteView:completion: instead.") + func easy_deleteElement(_ element: Any, completion: (() -> Void)?) { + easy.delete(element, completion: completion) + } +} diff --git a/Sources/Swift/EasyListAppend.swift b/Sources/Swift/EasyListAppend.swift new file mode 100644 index 0000000..de1e8f3 --- /dev/null +++ b/Sources/Swift/EasyListAppend.swift @@ -0,0 +1,105 @@ +// +// EasyListAppend.swift +// EasyListViewExample +// +// Created by carefree on 2022/10/7. +// Copyright © 2022 carefree. All rights reserved. +// + +import UIKit +import EasyCompatible + +public extension EasyExtension where Base: UIScrollView { + /** + 添加一个视图元素 + + * parameter viewClosure: 视图闭包 + + * returns: 自定义配置项 + */ + @discardableResult + func appendView(_ viewClosure: () -> UIView) -> EasyListAttributes { + return appendView(viewClosure()) + } + + /** + 添加一个视图元素 + + * parameter view: 视图 + + * returns: 自定义配置项 + */ + @discardableResult + func appendView(_ view: UIView) -> EasyListAttributes { + let scrollView = base + + //移除旧的约束 + searchConstraintsIn(scrollView, with: [ + .first(scrollView, .bottom), + .second(scrollView, .bottom) + ]).forEach { $0.isActive = false } + //添加子视图 + var contentView = EasyListContentView() + var isDisposable = false + if let disposableView = view as? EasyListContentView { + //动态元素 + contentView = disposableView + isDisposable = true + } else { + //静态元素 + var staticView = view + if let cell = staticView as? UITableViewCell { + staticView = cell.contentView + coordinator.cells[contentView] = cell + } + staticView.translatesAutoresizingMaskIntoConstraints = false + contentView.addSubview(staticView) + } + + guard let view = contentView.subviews.first else { + return EasyListAttributes() + } + + var insets = coordinator.globalEdgeInsets + insets.top = insets.top + coordinator.globalSpacing + + let leadingConstraint = addConstraint(for: contentView, item1: view, attr1: .leading, item2: contentView, attr2: .leading, constant: insets.left) + let trailingConstraint = addConstraint(for: contentView, item1: view, attr1: .trailing, item2: contentView, attr2: .trailing, constant: -insets.right) + let topConstraint = addConstraint(for: contentView, item1: view, attr1: .top, item2: contentView, attr2: .top, constant: insets.top) + let bottomConstraint = addConstraint(for: contentView, item1: view, attr1: .bottom, item2: contentView, attr2: .bottom, constant: -insets.bottom) + + contentView.clipsToBounds = coordinator.globalClipsToBounds + contentView.translatesAutoresizingMaskIntoConstraints = false + scrollView.addSubview(contentView) + + addConstraint(for: scrollView, item1: scrollView, attr1: .width, item2: contentView, attr2: .width) + addConstraint(for: scrollView, item1: contentView, attr1: .leading, item2: scrollView, attr2: .leading) + addConstraint(for: scrollView, item1: contentView, attr1: .trailing, item2: scrollView, attr2: .trailing) + addConstraint(for: scrollView, item1: contentView, attr1: .bottom, item2: scrollView, attr2: .bottom) + if let lastView = coordinator.elements.last?.view { + addConstraint(for: scrollView, item1: contentView, attr1: .top, item2: lastView, attr2: .bottom) + } else { + addConstraint(for: scrollView, item1: contentView, attr1: .top, item2: scrollView, attr2: .top) + } + + var element = Element(view: contentView, insets: insets) + coordinator.elements.append(element) + if isDisposable { + coordinator.disposableElements.append(Element(view: contentView, insets: insets)) + } + + if coordinator.onBatchUpdate { + element.inserting = true + } + + var attributes = EasyListAttributes() + attributes.coordinator = coordinator + attributes.element = element + attributes.leadingConstraint = leadingConstraint + attributes.trailingConstraint = trailingConstraint + attributes.topConstraint = topConstraint + attributes.bottomConstraint = bottomConstraint + + return attributes + } +} diff --git a/Sources/Swift/EasyListAppendDeprecated.swift b/Sources/Swift/EasyListAppendDeprecated.swift new file mode 100644 index 0000000..62d98b6 --- /dev/null +++ b/Sources/Swift/EasyListAppendDeprecated.swift @@ -0,0 +1,114 @@ +// +// EasyListAppendDeprecated.swift +// EasyListViewExample +// +// Created by carefree on 2022/10/7. +// Copyright © 2022 carefree. All rights reserved. +// + +import UIKit +import EasyCompatible + +public extension EasyExtension where Base: UIScrollView { + /** + 添加一个视图元素 + + * parameter viewOrClosure: 视图或闭包 + * parameter spacing: 与上一个视图的间距 + */ + @available(*, deprecated, renamed: "appendView(_:)", message: "Please use appendView(_:) instead.") + func append(_ viewOrClosure: Any, spacing: CGFloat = 0) { + var inset = coordinator.globalEdgeInsets + inset.top = spacing + append(viewOrClosure, with: inset) + } + + /** + 添加一个视图元素 + + * parameter viewOrClosure: 视图或闭包 + * parameter identifier: 视图唯一标识 + * parameter spacing: 与上一个视图的间距 + */ + @available(*, deprecated, renamed: "appendView(_:)", message: "Please use appendView(_:) instead.") + func append(_ viewOrClosure: Any, for identifier: String = "", spacing: CGFloat = 0) { + var inset = coordinator.globalEdgeInsets + inset.top = spacing + append(viewOrClosure, with: inset, for: identifier) + } + + /** + 添加一个视图元素 + + * parameter viewOrClosure: 视图或闭包 + * parameter insets: 视图自定义的间距 + * parameter identifier: 视图唯一标识 + */ + @available(*, deprecated, renamed: "appendView(_:)", message: "Please use appendView(_:) instead.") + func append(_ viewOrClosure: Any, with insets: UIEdgeInsets, for identifier: String = "") { + let scrollView = base + + //移除旧的约束 + searchConstraintsIn(scrollView, with: [ + .first(scrollView, .bottom), + .second(scrollView, .bottom) + ]).forEach { $0.isActive = false } + //添加子视图 + var contentView = EasyListContentView() + var isDisposable = false + if let disposableView = viewOrClosure as? EasyListContentView { + //动态元素 + contentView = disposableView + isDisposable = true + } else if let staticView = viewOrClosure as? UIView { + //静态元素 + var view = staticView + if let cell = view as? UITableViewCell { + view = cell.contentView + coordinator.cells[contentView] = cell + } + view.translatesAutoresizingMaskIntoConstraints = false + contentView.addSubview(view) + } else if let closure = viewOrClosure as? () -> UIView { + //闭包 + var view = closure() + if let cell = view as? UITableViewCell { + view = cell.contentView + coordinator.cells[contentView] = cell + } + view.translatesAutoresizingMaskIntoConstraints = false + contentView.addSubview(view) + } + + guard let view = contentView.subviews.first else { return } + + addConstraint(for: contentView, item1: view, attr1: .leading, item2: contentView, attr2: .leading, constant: insets.left) + addConstraint(for: contentView, item1: view, attr1: .trailing, item2: contentView, attr2: .trailing, constant: -insets.right) + addConstraint(for: contentView, item1: view, attr1: .top, item2: contentView, attr2: .top, constant: insets.top) + addConstraint(for: contentView, item1: view, attr1: .bottom, item2: contentView, attr2: .bottom, constant: -insets.bottom) + + contentView.clipsToBounds = true + contentView.translatesAutoresizingMaskIntoConstraints = false + scrollView.addSubview(contentView) + + addConstraint(for: scrollView, item1: scrollView, attr1: .width, item2: contentView, attr2: .width) + addConstraint(for: scrollView, item1: contentView, attr1: .leading, item2: scrollView, attr2: .leading) + addConstraint(for: scrollView, item1: contentView, attr1: .trailing, item2: scrollView, attr2: .trailing) + addConstraint(for: scrollView, item1: contentView, attr1: .bottom, item2: scrollView, attr2: .bottom) + if let lastView = coordinator.elements.last?.view { + addConstraint(for: scrollView, item1: contentView, attr1: .top, item2: lastView, attr2: .bottom) + } else { + addConstraint(for: scrollView, item1: contentView, attr1: .top, item2: scrollView, attr2: .top) + } + + var element = Element(view: contentView, insets: insets, identifier: identifier) + coordinator.elements.append(element) + if isDisposable { + coordinator.disposableElements.append(Element(view: contentView, insets: insets, identifier: identifier)) + } + + if coordinator.onBatchUpdate { + element.inserting = true + } + } +} diff --git a/Sources/Swift/EasyListAttributes.swift b/Sources/Swift/EasyListAttributes.swift new file mode 100644 index 0000000..e2dd3c0 --- /dev/null +++ b/Sources/Swift/EasyListAttributes.swift @@ -0,0 +1,86 @@ +// +// EasyListAttributes.swift +// EasyListView +// +// Created by carefree on 2022/10/9. +// + +import UIKit + +public struct EasyListAttributes { + internal var coordinator: EasyListCoordinator? + internal var element: Element? + internal var leadingConstraint: NSLayoutConstraint? + internal var trailingConstraint: NSLayoutConstraint? + internal var topConstraint: NSLayoutConstraint? + internal var bottomConstraint: NSLayoutConstraint? +} + +public extension EasyListAttributes { + /** + 设置唯一标识 + + * parameter identifier: 标识字符串 + + * returns: 自定义配置项 + */ + @discardableResult + func identifier(_ identifier: String) -> Self { + if let coordinator = coordinator, let element = element { + if let index = coordinator.elements.firstIndex(of: element) { + var newElement = coordinator.elements[index] + newElement.identifier = identifier + coordinator.elements[index] = newElement + } + if let index = coordinator.disposableElements.firstIndex(of: element) { + var newElement = coordinator.elements[index] + newElement.identifier = identifier + coordinator.elements[index] = newElement + } + } + + return self + } + + /** + 设置内间距 + + * parameter insets: 内间距 + + * returns: 自定义配置项 + */ + @discardableResult + func insets(_ insets: UIEdgeInsets) -> Self { + leadingConstraint?.constant = insets.left + trailingConstraint?.constant = -insets.right + topConstraint?.constant = insets.top + bottomConstraint?.constant = -insets.bottom + return self + } + + /** + 设置与上一元素的间距 + + * parameter spacing: 间距 + + * returns: 自定义配置项 + */ + @discardableResult + func spacing(_ spacing: CGFloat) -> Self { + topConstraint?.constant = spacing + return self + } + + /** + 设置超出部分是否裁剪 + + * parameter clipsToBounds: 是否裁剪 + + * returns: 自定义配置项 + */ + @discardableResult + func clipsToBounds(_ clipsToBounds: Bool) -> Self { + element?.view.clipsToBounds = clipsToBounds + return self + } +} diff --git a/Sources/EasyListConstraint.swift b/Sources/Swift/EasyListConstraint.swift similarity index 100% rename from Sources/EasyListConstraint.swift rename to Sources/Swift/EasyListConstraint.swift diff --git a/Sources/EasyListCoordinator.swift b/Sources/Swift/EasyListCoordinator.swift similarity index 75% rename from Sources/EasyListCoordinator.swift rename to Sources/Swift/EasyListCoordinator.swift index b867c22..b6f88ff 100644 --- a/Sources/EasyListCoordinator.swift +++ b/Sources/Swift/EasyListCoordinator.swift @@ -15,16 +15,20 @@ public enum EasyListUpdateOption: Int { case noLayout //不进行布局 } -@objcMembers -open class EasyListCoordinator: NSObject { +internal struct Element: Equatable { + var view: EasyListContentView + var insets: UIEdgeInsets = .zero + var identifier: String? + var deleting: Bool = false + var inserting: Bool = false - internal struct Element { - var view: EasyListContentView - var insets: UIEdgeInsets = .zero - var identifier: String? - var deleting: Bool = false - var inserting: Bool = false + static func == (lhs: Self, rhs: Self) -> Bool { + return lhs.view == rhs.view } +} + +@objcMembers +open class EasyListCoordinator: NSObject { public weak private(set) var scrollView: UIScrollView? @@ -32,6 +36,8 @@ open class EasyListCoordinator: NSObject { public var globalEdgeInsets: UIEdgeInsets = .zero //全局元素间距 public var globalSpacing: CGFloat = 0 + //超出部分裁剪,默认为true + public var globalClipsToBounds: Bool = true //动画持续时间(包括插入、删除),为0则无动画 public var animationDuration: TimeInterval = 0.3 diff --git a/Sources/Swift/EasyListDelete.swift b/Sources/Swift/EasyListDelete.swift new file mode 100644 index 0000000..51d7616 --- /dev/null +++ b/Sources/Swift/EasyListDelete.swift @@ -0,0 +1,63 @@ +// +// EasyListDelete.swift +// EasyListViewExample +// +// Created by carefree on 2022/10/7. +// Copyright © 2022 carefree. All rights reserved. +// + +import UIKit +import EasyCompatible + +public extension EasyExtension where Base: UIScrollView { + /** + 删除一个视图元素 + + * parameter view: 要删除的视图,可以是UIView,也可以是视图的唯一标识 + * parameter completion: 删除完成后的回调 + */ + func deleteView(_ view: Any, completion: (() -> Void)? = nil) { + let elements = coordinator.elements + + var targetView: UIView? + if let string = view as? String { + targetView = elements.first { $0.identifier == string }?.view + } + if let cell = view as? UITableViewCell { + targetView = coordinator.cells.first { $0.value == cell }?.key + } else if let view = view as? UIView { + targetView = elements.first { $0.view == view.superview }?.view + } + assert(targetView != nil, "invalid element") + + coordinator.elements = coordinator.elements.map { + var tmp = $0 + if targetView == tmp.view && !tmp.deleting { + tmp.deleting = true + } + return tmp + } + + if coordinator.onBatchUpdate { + completion?() + return + } + + animateDeletion(completion: { + self.reloadDisposableIfNeed() + completion?() + }, duration: coordinator.animationDuration) + } + + /** + 删除所有视图元素 + + */ + func deleteAll() { + coordinator.elements.forEach { + $0.view.removeFromSuperview() + } + coordinator.elements.removeAll() + coordinator.disposableElements.removeAll() + } +} diff --git a/Sources/Swift/EasyListDeleteDeprecated.swift b/Sources/Swift/EasyListDeleteDeprecated.swift new file mode 100644 index 0000000..fecee9d --- /dev/null +++ b/Sources/Swift/EasyListDeleteDeprecated.swift @@ -0,0 +1,51 @@ +// +// EasyListDeleteDeprecated.swift +// EasyListView +// +// Created by carefree on 2022/10/10. +// + +import UIKit +import EasyCompatible + +public extension EasyExtension where Base: UIScrollView { + /** + 删除一个视图元素 + + * parameter element: 要删除的视图,可以是UIView,也可以是视图的唯一标识 + * parameter completion: 删除完成后的回调 + */ + @available(*, deprecated, renamed: "deleteView(_:completion:)", message: "Please use deleteView(_:completion:) instead.") + func delete(_ element: Any, completion: (() -> Void)? = nil) { + let elements = coordinator.elements + + var targetView: UIView? + if let string = element as? String { + targetView = elements.first { $0.identifier == string }?.view + } + if let cell = element as? UITableViewCell { + targetView = coordinator.cells.first { $0.value == cell }?.key + } else if let view = element as? UIView { + targetView = elements.first { $0.view == view.superview }?.view + } + assert(targetView != nil, "invalid element") + + coordinator.elements = coordinator.elements.map { + var tmp = $0 + if targetView == tmp.view && !tmp.deleting { + tmp.deleting = true + } + return tmp + } + + if coordinator.onBatchUpdate { + completion?() + return + } + + animateDeletion(completion: { + self.reloadDisposableIfNeed() + completion?() + }, duration: coordinator.animationDuration) + } +} diff --git a/Sources/Swift/EasyListDisposable.swift b/Sources/Swift/EasyListDisposable.swift new file mode 100644 index 0000000..50cdce5 --- /dev/null +++ b/Sources/Swift/EasyListDisposable.swift @@ -0,0 +1,124 @@ +// +// EasyListDisposable.swift +// EasyListViewExample +// +// Created by carefree on 2022/10/8. +// Copyright © 2022 carefree. All rights reserved. +// + +import UIKit +import EasyCompatible + +public extension EasyExtension where Base: UIScrollView { + /** + 生成自释放元素 + + * parameter maker: 闭包 + + * returns: 生成的视图 + */ + func disposableView(with maker: @escaping () -> UIView) -> UIView { + let contentView = EasyListContentView() + var view = maker() + if let cell = view as? UITableViewCell { + view = cell.contentView + coordinator.cells[contentView] = cell + } + view.translatesAutoresizingMaskIntoConstraints = false + contentView.addSubview(view) + contentView.disposableMaker = maker + + return contentView + } + + /** + 刷新数据 + + */ + func reloadDisposableData() { + coordinator.disposableElements.forEach { + $0.view.subviews.first?.removeFromSuperview() + } + reloadDisposableIfNeed() + } + + /** + 触发自释放机制 + + */ + func triggerDisposable() { + let scrollView = base + + let offset = scrollView.contentOffset.y + let range = scrollView.frame.height + let minY = offset - range + let maxY = offset + range + range + + coordinator.disposableElements.forEach { element in + let contentView = element.view + let frame = contentView.frame + guard let maker = contentView.disposableMaker else { return } + + if frame.maxY >= minY && frame.minY <= maxY { + //在可视范围内 + if contentView.subviews.count == 0 { + //恢复子视图 + var view = maker() + if let cell = view as? UITableViewCell { + view = cell.contentView + coordinator.cells[contentView] = cell + } + view.translatesAutoresizingMaskIntoConstraints = false + contentView.addSubview(view) + addConstraint(for: contentView, item1: view, attr1: .leading, item2: contentView, attr2: .leading, constant: element.insets.left) + addConstraint(for: contentView, item1: view, attr1: .trailing, item2: contentView, attr2: .trailing, constant: -element.insets.right) + addConstraint(for: contentView, item1: view, attr1: .top, item2: contentView, attr2: .top, constant: element.insets.top) + addConstraint(for: contentView, item1: view, attr1: .bottom, item2: contentView, attr2: .bottom, constant: -element.insets.bottom) + //删除height约束 + contentView.constraints.first { $0.firstAttribute == .height }?.isActive = false + } + } else { + //不在可视范围内 + if contentView.subviews.count > 0 { + //移除子视图,回收内存 + addConstraint(for: contentView, item1: contentView, attr1: .height, item2: nil, attr2: .notAnAttribute, constant: frame.height) + coordinator.cells.removeValue(forKey: contentView) + contentView.subviews.forEach { $0.removeFromSuperview() } + } + } + } + } + + /** + 获取指定下标的自释放元素 + + * parameter index: 下标 + + * returns: 找到的视图 + */ + func getDisposableElement(at index: Int) -> UIView? { + if index >= coordinator.disposableElements.count { + return nil + } + let contentView = coordinator.disposableElements[index].view + if let cell = coordinator.cells[contentView] { + return cell + } + return contentView.subviews.first + } + + /** + 获取所有可视的自释放元素 + + * returns: 找到的视图集合 + */ + var visibleDisposableElements: [UIView] { + return coordinator.disposableElements.compactMap { + let contentView = $0.view + if let cell = coordinator.cells[contentView] { + return cell + } + return contentView.subviews.first + } + } +} diff --git a/Sources/Swift/EasyListExtension.swift b/Sources/Swift/EasyListExtension.swift new file mode 100644 index 0000000..a312b9a --- /dev/null +++ b/Sources/Swift/EasyListExtension.swift @@ -0,0 +1,332 @@ +// +// EasyListExtension.swift +// EasyListViewExample +// +// Created by carefree on 2020/8/8. +// Copyright © 2020 carefree. All rights reserved. +// + +import UIKit +import EasyCompatible + +private var EasyListCoordinatorKey = "EasyListCoordinatorKey" +//添加easy扩展 +extension UIScrollView: EasyCompatible { } + +public extension EasyExtension where Base: UIScrollView { + + internal enum SearchCondition { + case first(UIView, NSLayoutConstraint.Attribute) + case second(UIView, NSLayoutConstraint.Attribute) + case both(UIView?, NSLayoutConstraint.Attribute, + UIView?, NSLayoutConstraint.Attribute) + } + + // MARK: - Coordinator + var coordinator: EasyListCoordinator { + get { + if let coordinator = objc_getAssociatedObject(self.base, &EasyListCoordinatorKey) as? EasyListCoordinator { + return coordinator + } + let coordinator = EasyListCoordinator(with: self.base) + objc_setAssociatedObject(self.base, &EasyListCoordinatorKey, coordinator, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) + return coordinator + } + set { + objc_setAssociatedObject(self.base, &EasyListCoordinatorKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + + // MARK: - BatchUpdate + /** + 开始批量更新操作 + + * parameter option: 更新方式 + * Note: 需和endUpdates成对使用。 + */ + func beginUpdates(option: EasyListUpdateOption = .animatedLayout) { + coordinator.onBatchUpdate = true + coordinator.batchUpdateOption = option + } + + /** + 完成批量更新操作 + + * parameter completion: 更新完成后的回调 + */ + func endUpdates(_ completion: (() -> Void)? = nil) { + coordinator.onBatchUpdate = false + + let insertingCount = coordinator.elements.filter { $0.inserting }.count + let deletingCount = coordinator.elements.filter { $0.deleting }.count + + //不执行layout + if coordinator.batchUpdateOption == .noLayout { + //清理标记 + if insertingCount > 0 { + lastStepForInserting() + } + if deletingCount > 0 { + lastStepForDeleting() + } + //完成回调 + completion?() + return + } + + //无动画的layout + if coordinator.batchUpdateOption == .onlyLayout { + //更新约束 + resetConstraintsForDeleting() + base.layoutIfNeeded() + self.reloadDisposableIfNeed() + //清理标记 + if insertingCount > 0 { + lastStepForInserting() + } + if deletingCount > 0 { + lastStepForDeleting() + } + //完成回调 + completion?() + return + } + + //带动画的layout + let duration = coordinator.animationDuration + if insertingCount > 0 && deletingCount > 0 { + //先执行插入动画 + self.animateInsertion(completion: { + //再执行删除动画 + self.animateDeletion(completion: completion, duration: duration / 2) + }, duration: duration / 2) + } else if insertingCount > 0 { + //执行插入动画 + self.animateInsertion(completion: completion, duration: duration) + } else if deletingCount > 0 { + //执行删除动画 + self.animateDeletion(completion: completion, duration: duration) + } else { + //兜底代码 + self.reloadDisposableIfNeed() + completion?() + } + } + + // MARK: - Getter + /** + 获取视图元素 + + * parameter identifier: 视图唯一标识 + + * returns: 找到的视图 + */ + func getElement(identifier: String) -> UIView? { + let getView = coordinator.elements.first { $0.identifier == identifier }?.view + guard let contentView = getView else { + return nil + } + if let cell = coordinator.cells[contentView] { + return cell + } + return contentView.subviews.first + } + + // MARK: - Internal + //插入动画 + internal func animateInsertion(completion: (() -> Void)? = nil, duration: TimeInterval) { + let scrollView = base + let elements = coordinator.elements + + //替换bottom约束为高度约束 + let insertingViews = elements.filter { $0.inserting }.map { $0.view } + var heightConstraints = [(constraint: NSLayoutConstraint, subview: UIView, offset: CGFloat)]() + var bottomConstraints = [NSLayoutConstraint]() + for view in insertingViews { + var offset: CGFloat = 0 + searchConstraintsIn(view, with: [ + .first(view, .top), + .second(view, .top), + .first(view, .bottom), + .second(view, .bottom) + ]).forEach { + if $0.firstAttribute == .top || $0.secondAttribute == .top { + offset += $0.constant + } else { + bottomConstraints.append($0) + $0.isActive = false + offset -= $0.constant + } + } + let constraint = addConstraint(for: view, item1: view, attr1: .height, item2: nil, attr2: .notAnAttribute) + heightConstraints.append((constraint, view.subviews.first!, offset)) + } + + scrollView.layoutIfNeeded() + //更新高度约束 + heightConstraints.forEach { + $0.constraint.constant = $0.subview.frame.size.height + $0.offset + } + UIView.animate(withDuration: duration, animations: { + scrollView.layoutIfNeeded() + }) { _ in + self.reloadDisposableIfNeed() + //删除height约束 + heightConstraints.forEach { + $0.constraint.isActive = false + } + //恢复bottom约束 + bottomConstraints.forEach { + $0.isActive = true + } + self.lastStepForInserting() + completion?() + } + } + + // 删除动画 + internal func animateDeletion(completion: (() -> Void)? = nil, duration: TimeInterval) { + let scrollView = base + let elements = coordinator.elements + + //替换bottom约束为高度约束 + let deletingViews = elements.filter { $0.deleting }.map { $0.view } + if deletingViews.count == 0 { + completion?() + return + } + for view in deletingViews { + let height = view.frame.size.height + view.constraints.forEach { + if let item = $0.firstItem as? UIView, item == view && $0.firstAttribute == .bottom { + $0.isActive = false + } + if let item = $0.secondItem as? UIView, item == view && $0.secondAttribute == .bottom { + $0.isActive = false + } + } + let heightConstraint = addConstraint(for: view, item1: view, attr1: .height, item2: nil, attr2: .notAnAttribute, constant: height) + view.layoutIfNeeded() + + heightConstraint.constant = 0 + } + + //更新布局 + UIView.animate(withDuration: duration * 3 / 4, animations: { + scrollView.layoutIfNeeded() + }) { _ in + //更新约束 + self.resetConstraintsForDeleting() + UIView.animate(withDuration: duration / 4, animations: { + scrollView.layoutIfNeeded() + }) { _ in + //完成后移除相关元素 + self.lastStepForDeleting() + completion?() + } + } + } + + //刷新 + internal func reloadDisposableIfNeed() { + triggerDisposable() + } + + //查找符合条件的约束 + internal func searchConstraintsIn(_ view: UIView, with conditions: [SearchCondition]) -> [NSLayoutConstraint] { + var results = [NSLayoutConstraint]() + for constraint in view.constraints { + for condition in conditions { + switch condition { + case .first(let firstItem, let firstAttribute): + //匹配first + guard let item = constraint.firstItem as? UIView else { break } + if item == firstItem && constraint.firstAttribute == firstAttribute { + results.append(constraint) + } + case .second(let secondItem, let secondAttribute): + //匹配second + guard let item = constraint.secondItem as? UIView else { break } + if item == secondItem && constraint.secondAttribute == secondAttribute { + results.append(constraint) + } + case .both(let firstItem, let firstAttribute, let secondItem, let secondAttribute): + //匹配全部 + guard let first = constraint.firstItem as? UIView, let second = constraint.secondItem as? UIView else { + break + } + if first == firstItem && + second == secondItem && + constraint.firstAttribute == firstAttribute && + constraint.secondAttribute == secondAttribute { + results.append(constraint) + } + } + } + } + return results + } + + //针对删除的元素重新构建约束 + internal func resetConstraintsForDeleting() { + let scrollView = base + + var list = [(UIView, UIView)]() + var previousView: UIView = scrollView + var nextView: UIView? + var flag = false + for element in coordinator.elements { + if element.deleting { + flag = true + continue + } + if flag { + nextView = element.view + } else { + previousView = element.view + } + if let view = nextView { + list.append((previousView, view)) + + previousView = element.view + nextView = nil + flag = false + } + } + if flag { + list.append((previousView, scrollView)) + } + for (previousView, nextView) in list { + if previousView == nextView { + continue + } + if previousView == scrollView { + addConstraint(for: scrollView, item1: nextView, attr1: .top, item2: previousView, attr2: .top) + } else if nextView == scrollView { + addConstraint(for: scrollView, item1: nextView, attr1: .bottom, item2: previousView, attr2: .bottom) + } else { + addConstraint(for: scrollView, item1: nextView, attr1: .top, item2: previousView, attr2: .bottom) + } + } + } + + internal func lastStepForDeleting() { + coordinator.elements.filter { + return $0.deleting + }.map { + return $0.view + }.forEach { + $0.removeFromSuperview() + self.coordinator.cells.removeValue(forKey: $0) + } + coordinator.elements.removeAll { $0.deleting } + } + + internal func lastStepForInserting() { + coordinator.elements = coordinator.elements.map { + var tmp = $0 + tmp.inserting = false + return tmp + } + } +} diff --git a/Sources/Swift/EasyListInsert.swift b/Sources/Swift/EasyListInsert.swift new file mode 100644 index 0000000..fd7f1d4 --- /dev/null +++ b/Sources/Swift/EasyListInsert.swift @@ -0,0 +1,243 @@ +// +// EasyListInsert.swift +// EasyListViewExample +// +// Created by carefree on 2022/10/7. +// Copyright © 2022 carefree. All rights reserved. +// + +import UIKit +import EasyCompatible + +public extension EasyExtension where Base: UIScrollView { + /** + 在目标之后插入一个视图元素 + + * parameter viewClosure: 视图闭包 + * parameter element: 前一个视图元素,可以是UIView,也可以是视图唯一标识 + + * returns: 自定义配置项 + */ + @discardableResult + func insertView(_ viewClosure: () -> UIView, after element: Any) -> EasyListAttributes { + return insertView(viewClosure(), after: element) + } + + /** + 在目标之后插入一个视图元素 + + * parameter view: 视图 + * parameter element: 前一个视图元素,可以是UIView,也可以是视图唯一标识 + + * returns: 自定义配置项 + */ + @discardableResult + func insertView(_ view: UIView, after element: Any) -> EasyListAttributes { + let scrollView = base + let elements = coordinator.elements + + var relateView: UIView? + if let string = element as? String { + relateView = elements.first { $0.identifier == string }?.view + } + if let cell = element as? UITableViewCell { + relateView = coordinator.cells.first { $0.value == cell }?.key + } else if let view = element as? UIView { + if view == scrollView { + relateView = view + } else { + relateView = elements.first { $0.view == view.superview }?.view + } + } + assert(relateView != nil, "invalid element") + + //查找前后视图及下标 + var previousView: UIView? + var nextView: UIView = scrollView + var flag = false + var index = -1 + if relateView == scrollView { + previousView = scrollView + flag = true + index = 0 + } + for i in 0 ..< elements.count { + if elements[i].view == relateView { + previousView = elements[i].view + flag = true + index = i + 1 + continue + } else if flag { + nextView = elements[i].view + break + } + } + + return insertView(view, previousView: previousView, nextView: nextView, index: index) + } + + /** + 在目标之前插入一个视图元素 + + * parameter viewClosure: 视图闭包 + * parameter element: 后一个视图元素,可以是UIView,也可以是视图唯一标识 + + * returns: 自定义配置项 + */ + @discardableResult + func insertView(_ viewClosure: () -> UIView, before element: Any) -> EasyListAttributes { + return insertView(viewClosure(), before: element) + } + + /** + 在目标之前插入一个视图元素 + + * parameter view: 视图 + * parameter element: 后一个视图元素,可以是UIView,也可以是视图唯一标识 + + * returns: 自定义配置项 + */ + @discardableResult + func insertView(_ view: UIView, before element: Any) -> EasyListAttributes { + let scrollView = base + let elements = coordinator.elements + + var relateView: UIView? + if let string = element as? String { + relateView = elements.first { $0.identifier == string }?.view + } + if let cell = element as? UITableViewCell { + relateView = coordinator.cells.first { $0.value == cell }?.key + } else if let view = element as? UIView { + if view == scrollView { + relateView = view + } else { + relateView = elements.first { $0.view == view.superview }?.view + } + } + assert(relateView != nil, "invalid element") + + //查找前后视图及下标 + var previousView: UIView = scrollView + var nextView: UIView? + var flag = false + var index = -1 + if relateView == scrollView { + nextView = scrollView + flag = true + index = elements.count + } + for i in (0 ..< elements.count).reversed() { + if elements[i].view == relateView { + nextView = elements[i].view + flag = true + index = i + continue + } else if flag { + previousView = elements[i].view + break + } + } + + return insertView(view, previousView: previousView, nextView: nextView, index: index) + } + + /** + 插入一个视图元素 + + * parameter view: 视图 + * parameter previousView: 前一个视图元素 + * parameter nextView: 后一个视图元素 + * parameter index: 插入的下标 + + * returns: 自定义配置项 + */ + @discardableResult + private func insertView(_ view: UIView, previousView: UIView?, nextView: UIView?, index: Int) -> EasyListAttributes { + let scrollView = base + + //移除旧的约束 + searchConstraintsIn(scrollView, with: [ + .both(previousView, .top, nextView, .top), + .both(previousView, .top, nextView, .bottom), + .both(previousView, .bottom, nextView, .top), + .both(previousView, .bottom, nextView, .bottom), + .both(nextView, .top, previousView, .top), + .both(nextView, .top, previousView, .bottom), + .both(nextView, .bottom, previousView, .top), + .both(nextView, .bottom, previousView, .bottom) + ]).forEach { $0.isActive = false } + //插入子视图 + var contentView = EasyListContentView() + var isDisposable = false + if let disposableView = view as? EasyListContentView { + //动态元素 + contentView = disposableView + isDisposable = true + } else { + //静态元素 + var staticView = view + if let cell = staticView as? UITableViewCell { + staticView = cell.contentView + coordinator.cells[contentView] = cell + } + staticView.translatesAutoresizingMaskIntoConstraints = false + contentView.addSubview(staticView) + } + + guard let view = contentView.subviews.first else { + return EasyListAttributes() + } + + var insets = coordinator.globalEdgeInsets + insets.top = insets.top + coordinator.globalSpacing + + let leadingConstraint = addConstraint(for: contentView, item1: view, attr1: .leading, item2: contentView, attr2: .leading, constant: insets.left) + let trailingConstraint = addConstraint(for: contentView, item1: view, attr1: .trailing, item2: contentView, attr2: .trailing, constant: -insets.right) + let topConstraint = addConstraint(for: contentView, item1: view, attr1: .top, item2: contentView, attr2: .top, constant: insets.top) + let bottomConstraint = addConstraint(for: contentView, item1: view, attr1: .bottom, item2: contentView, attr2: .bottom, constant: -insets.bottom) + + contentView.clipsToBounds = coordinator.globalClipsToBounds + contentView.translatesAutoresizingMaskIntoConstraints = false + scrollView.addSubview(contentView) + + addConstraint(for: scrollView, item1: scrollView, attr1: .width, item2: contentView, attr2: .width) + addConstraint(for: scrollView, item1: contentView, attr1: .leading, item2: scrollView, attr2: .leading) + addConstraint(for: scrollView, item1: contentView, attr1: .trailing, item2: scrollView, attr2: .trailing) + if previousView == scrollView { + addConstraint(for: scrollView, item1: contentView, attr1: .top, item2: previousView, attr2: .top) + } else { + addConstraint(for: scrollView, item1: contentView, attr1: .top, item2: previousView, attr2: .bottom) + } + if nextView == scrollView { + addConstraint(for: scrollView, item1: contentView, attr1: .bottom, item2: nextView, attr2: .bottom) + } else { + addConstraint(for: scrollView, item1: nextView!, attr1: .top, item2: contentView, attr2: .bottom) + } + + var element = Element(view: contentView, insets: insets) + element.inserting = true + coordinator.elements.insert(element, at: index) + if isDisposable { + var disposableIndex = 0 + for tmp in coordinator.disposableElements { + for i in 0 ..< index { + if tmp.view == coordinator.elements[i].view { + disposableIndex += 1 + } + } + } + coordinator.disposableElements.insert(Element(view: contentView, insets: insets), at: disposableIndex) + } + + var attributes = EasyListAttributes() + attributes.coordinator = coordinator + attributes.element = element + attributes.leadingConstraint = leadingConstraint + attributes.trailingConstraint = trailingConstraint + attributes.topConstraint = topConstraint + attributes.bottomConstraint = bottomConstraint + + return attributes + } +} diff --git a/Sources/Swift/EasyListInsertDeprecated.swift b/Sources/Swift/EasyListInsertDeprecated.swift new file mode 100644 index 0000000..719c39f --- /dev/null +++ b/Sources/Swift/EasyListInsertDeprecated.swift @@ -0,0 +1,223 @@ +// +// EasyListInsertDeprecated.swift +// EasyListViewExample +// +// Created by carefree on 2022/10/7. +// Copyright © 2022 carefree. All rights reserved. +// + +import UIKit +import EasyCompatible + +public extension EasyExtension where Base: UIScrollView { + /** + 插入一个视图元素 + + * parameter viewOrClosure: 视图或闭包 + * parameter element: 前一个视图元素,可以是UIView,也可以是视图唯一标识 + * parameter insets: 视图自定义的间距 + * parameter identifier: 视图唯一标识 + * parameter completion: 插入完成回调 + */ + @available(*, deprecated, renamed: "insertView(_:after:)", message: "Please use insertView(_:after:) instead.") + func insert(_ viewOrClosure: Any, after element: Any, with insets: UIEdgeInsets = .zero, for identifier: String = "", completion: (() -> Void)? = nil) { + let scrollView = base + let elements = coordinator.elements + + var relateView: UIView? + if let string = element as? String { + relateView = elements.first { $0.identifier == string }?.view + } + if let cell = element as? UITableViewCell { + relateView = coordinator.cells.first { $0.value == cell }?.key + } else if let view = element as? UIView { + if view == scrollView { + relateView = view + } else { + relateView = elements.first { $0.view == view.superview }?.view + } + } + assert(relateView != nil, "invalid element") + + //查找前后视图及下标 + var previousView: UIView? + var nextView: UIView = scrollView + var flag = false + var index = -1 + if relateView == scrollView { + previousView = scrollView + flag = true + index = 0 + } + for i in 0 ..< elements.count { + if elements[i].view == relateView { + previousView = elements[i].view + flag = true + index = i + 1 + continue + } else if flag { + nextView = elements[i].view + break + } + } + + insert(viewOrClosure, previousView: previousView, nextView: nextView, index: index, with: insets, for: identifier, completion: completion) + } + + /** + 插入一个视图元素 + + * parameter viewOrClosure: 视图或闭包 + * parameter element: 后一个视图元素,可以是UIView,也可以是视图唯一标识 + * parameter insets: 视图自定义的间距 + * parameter identifier: 视图唯一标识 + * parameter completion: 插入完成回调 + */ + @available(*, deprecated, renamed: "insertView(_:before:)", message: "Please use insertView(_:before:) instead.") + func insert(_ viewOrClosure: Any, before element: Any, with insets: UIEdgeInsets = .zero, for identifier: String = "", completion: (() -> Void)? = nil) { + let scrollView = base + let elements = coordinator.elements + + var relateView: UIView? + if let string = element as? String { + relateView = elements.first { $0.identifier == string }?.view + } + if let cell = element as? UITableViewCell { + relateView = coordinator.cells.first { $0.value == cell }?.key + } else if let view = element as? UIView { + if view == scrollView { + relateView = view + } else { + relateView = elements.first { $0.view == view.superview }?.view + } + } + assert(relateView != nil, "invalid element") + + //查找前后视图及下标 + var previousView: UIView = scrollView + var nextView: UIView? + var flag = false + var index = -1 + if relateView == scrollView { + nextView = scrollView + flag = true + index = elements.count + } + for i in (0 ..< elements.count).reversed() { + if elements[i].view == relateView { + nextView = elements[i].view + flag = true + index = i + continue + } else if flag { + previousView = elements[i].view + break + } + } + + insert(viewOrClosure, previousView: previousView, nextView: nextView, index: index, with: insets, for: identifier, completion: completion) + } + + /** + 插入一个视图元素 + + * parameter viewOrClosure: 视图或闭包 + * parameter previousView: 前一个视图元素 + * parameter nextView: 后一个视图元素 + * parameter index: 插入的下标 + * parameter insets: 视图自定义的间距 + * parameter identifier: 视图唯一标识 + * parameter completion: 插入完成回调 + */ + private func insert(_ viewOrClosure: Any, previousView: UIView?, nextView: UIView?, index: Int, with insets: UIEdgeInsets, for identifier: String, completion: (() -> Void)?) { + let scrollView = base + + //移除旧的约束 + searchConstraintsIn(scrollView, with: [ + .both(previousView, .top, nextView, .top), + .both(previousView, .top, nextView, .bottom), + .both(previousView, .bottom, nextView, .top), + .both(previousView, .bottom, nextView, .bottom), + .both(nextView, .top, previousView, .top), + .both(nextView, .top, previousView, .bottom), + .both(nextView, .bottom, previousView, .top), + .both(nextView, .bottom, previousView, .bottom) + ]).forEach { $0.isActive = false } + //插入子视图 + var contentView = EasyListContentView() + var isDisposable = false + if let disposableView = viewOrClosure as? EasyListContentView { + //动态元素 + contentView = disposableView + isDisposable = true + } else if let staticView = viewOrClosure as? UIView { + //静态元素 + var view = staticView + if let cell = view as? UITableViewCell { + view = cell.contentView + coordinator.cells[contentView] = cell + } + view.translatesAutoresizingMaskIntoConstraints = false + contentView.addSubview(view) + } else if let closure = viewOrClosure as? () -> UIView { + //闭包 + var view = closure() + if let cell = view as? UITableViewCell { + view = cell.contentView + coordinator.cells[contentView] = cell + } + view.translatesAutoresizingMaskIntoConstraints = false + contentView.addSubview(view) + } + + guard let view = contentView.subviews.first else { return } + + addConstraint(for: contentView, item1: view, attr1: .leading, item2: contentView, attr2: .leading, constant: insets.left) + addConstraint(for: contentView, item1: view, attr1: .trailing, item2: contentView, attr2: .trailing, constant: -insets.right) + addConstraint(for: contentView, item1: view, attr1: .top, item2: contentView, attr2: .top, constant: insets.top) + addConstraint(for: contentView, item1: view, attr1: .bottom, item2: contentView, attr2: .bottom, constant: -insets.bottom) + + contentView.clipsToBounds = true + contentView.translatesAutoresizingMaskIntoConstraints = false + scrollView.addSubview(contentView) + + addConstraint(for: scrollView, item1: scrollView, attr1: .width, item2: contentView, attr2: .width) + addConstraint(for: scrollView, item1: contentView, attr1: .leading, item2: scrollView, attr2: .leading) + addConstraint(for: scrollView, item1: contentView, attr1: .trailing, item2: scrollView, attr2: .trailing) + if previousView == scrollView { + addConstraint(for: scrollView, item1: contentView, attr1: .top, item2: previousView, attr2: .top) + } else { + addConstraint(for: scrollView, item1: contentView, attr1: .top, item2: previousView, attr2: .bottom) + } + if nextView == scrollView { + addConstraint(for: scrollView, item1: contentView, attr1: .bottom, item2: nextView, attr2: .bottom) + } else { + addConstraint(for: scrollView, item1: nextView!, attr1: .top, item2: contentView, attr2: .bottom) + } + + var element = Element(view: contentView, insets: insets, identifier: identifier) + element.inserting = true + coordinator.elements.insert(element, at: index) + if isDisposable { + var disposableIndex = 0 + for tmp in coordinator.disposableElements { + for i in 0 ..< index { + if tmp.view == coordinator.elements[i].view { + disposableIndex += 1 + } + } + } + coordinator.disposableElements.insert(Element(view: contentView, insets: insets, identifier: identifier), at: disposableIndex) + } + + if coordinator.onBatchUpdate { + completion?() + return + } + + animateInsertion(completion: { + self.reloadDisposableIfNeed() + completion?() + }, duration: coordinator.animationDuration) + } +} diff --git a/Sources/EasyListView.swift b/Sources/Swift/EasyListView.swift similarity index 100% rename from Sources/EasyListView.swift rename to Sources/Swift/EasyListView.swift