From 42d06273fcf21af08946052383d8742077e360dd Mon Sep 17 00:00:00 2001 From: Pavan Kataria Date: Wed, 15 Mar 2017 09:45:45 +0000 Subject: [PATCH 01/21] Created textfield --- Example/Pods/Pods.xcodeproj/project.pbxproj | 43 ++++++++++--------- .../Classes/DataTableSearchTextField.swift | 14 ++++++ 2 files changed, 37 insertions(+), 20 deletions(-) create mode 100644 SwiftDataTables/Classes/DataTableSearchTextField.swift diff --git a/Example/Pods/Pods.xcodeproj/project.pbxproj b/Example/Pods/Pods.xcodeproj/project.pbxproj index 503fb55..932ef16 100644 --- a/Example/Pods/Pods.xcodeproj/project.pbxproj +++ b/Example/Pods/Pods.xcodeproj/project.pbxproj @@ -9,6 +9,7 @@ /* Begin PBXBuildFile section */ 04D3A2072D43BBF4D1BFDFD45F859226 /* DataCellLayoutAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EE1F7C243C8D194CB6C5DFC46CE2597 /* DataCellLayoutAttributes.swift */; }; 04E67A60A59D89EDD0FA3954807BACA2 /* Pods-SwiftDataTables_Example-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 384C6C6A4148C520C98D0600D7393727 /* Pods-SwiftDataTables_Example-dummy.m */; }; + 057C454E1E7944B400B3F747 /* DataTableSearchTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 057C454D1E7944B400B3F747 /* DataTableSearchTextField.swift */; }; 081E967D67DC9BED078AAC67DDB50B6A /* SwiftDataTables.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 7CD548E01AB1C82543F72FC3ACDE740B /* SwiftDataTables.bundle */; }; 0C4C3FD1B0C3881E2A7BA491A0E3CDE7 /* DataHeaderFooter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F51A0022452EF1EFD995A3C901C8035 /* DataHeaderFooter.swift */; }; 13DC5749947421DFD00ECF07EDF28D52 /* SwiftDataTables-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 78A14C8773B4B9CD3ADB324703A6D84D /* SwiftDataTables-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -60,9 +61,10 @@ /* Begin PBXFileReference section */ 026CC3068F40BE2D05647A2410B36B3B /* Pods-SwiftDataTables_Tests-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-SwiftDataTables_Tests-resources.sh"; sourceTree = ""; }; + 057C454D1E7944B400B3F747 /* DataTableSearchTextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataTableSearchTextField.swift; sourceTree = ""; }; 09B4FE2CBBA7486FA032F19F7C6EC1D1 /* VirtualPositionTrackable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = VirtualPositionTrackable.swift; sourceTree = ""; }; - 1037553484562CE309A3013538712A90 /* Pods_SwiftDataTables_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_SwiftDataTables_Tests.framework; path = "Pods-SwiftDataTables_Tests.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; - 15D74D4F308C07A9FF50DFDA2A0736D9 /* Pods-SwiftDataTables_Example.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; path = "Pods-SwiftDataTables_Example.modulemap"; sourceTree = ""; }; + 1037553484562CE309A3013538712A90 /* Pods_SwiftDataTables_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SwiftDataTables_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 15D74D4F308C07A9FF50DFDA2A0736D9 /* Pods-SwiftDataTables_Example.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = "Pods-SwiftDataTables_Example.modulemap"; sourceTree = ""; }; 18B3638F5AD13E6EBCB7FBA837D1D5AD /* Pods-SwiftDataTables_Tests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-SwiftDataTables_Tests-acknowledgements.markdown"; sourceTree = ""; }; 1AD804FA3D8F3F6364A5D9D007B80856 /* SwiftDataTable+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "SwiftDataTable+Extensions.swift"; sourceTree = ""; }; 24C5B75DC8BB1D3AC33E13F348A6FD17 /* DataStore.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DataStore.swift; sourceTree = ""; }; @@ -75,11 +77,11 @@ 3D230D9B285E4DB6BE57283D0DA369B9 /* CollectionViewSupplementaryElementRepresentable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CollectionViewSupplementaryElementRepresentable.swift; sourceTree = ""; }; 3F51A0022452EF1EFD995A3C901C8035 /* DataHeaderFooter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DataHeaderFooter.swift; sourceTree = ""; }; 3FCF927BF691F6711D8A34DA24DE0727 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 4A7A00092F7F68FE9EB3EDD8772E3635 /* SwiftDataTables.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; path = SwiftDataTables.modulemap; sourceTree = ""; }; + 4A7A00092F7F68FE9EB3EDD8772E3635 /* SwiftDataTables.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = SwiftDataTables.modulemap; sourceTree = ""; }; 4AF636A6C261B4B22000184FC87CE66A /* Pods-SwiftDataTables_Example-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-SwiftDataTables_Example-resources.sh"; sourceTree = ""; }; 5277C1C4F649828D9CEE62AF4D307B53 /* Pods-SwiftDataTables_Example-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-SwiftDataTables_Example-umbrella.h"; sourceTree = ""; }; 58396C00E501273D8D517F4680C5497B /* DataCell.xib */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file.xib; path = DataCell.xib; sourceTree = ""; }; - 5CBE07CBEF0A9F6D1115A9DCD2EEA50C /* column-sort-ascending.png */ = {isa = PBXFileReference; includeInIndex = 1; path = "column-sort-ascending.png"; sourceTree = ""; }; + 5CBE07CBEF0A9F6D1115A9DCD2EEA50C /* column-sort-ascending.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = "column-sort-ascending.png"; sourceTree = ""; }; 5FE39D66642A56668EE1C80FE219DEBC /* DataHeaderFooter.xib */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file.xib; path = DataHeaderFooter.xib; sourceTree = ""; }; 5FF66442B3706F72C3360B21A22E47D8 /* MenuLengthHeaderViewModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = MenuLengthHeaderViewModel.swift; sourceTree = ""; }; 692C83EA7BDB5F20630C8A087F6D4189 /* DataHeaderFooterViewModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DataHeaderFooterViewModel.swift; sourceTree = ""; }; @@ -97,18 +99,18 @@ 86C31390A6D99B60A5D28F7BF13FB249 /* Pods-SwiftDataTables_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-SwiftDataTables_Tests.release.xcconfig"; sourceTree = ""; }; 86FA0E63F942A371F612D17FC46F527F /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 8EE1F7C243C8D194CB6C5DFC46CE2597 /* DataCellLayoutAttributes.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DataCellLayoutAttributes.swift; sourceTree = ""; }; - 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 96CB8888EBCDDEA599EB73C4DB608B5A /* DataCell.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DataCell.swift; sourceTree = ""; }; - 9A707D5DA18A0996ADF3231840835908 /* Pods_SwiftDataTables_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_SwiftDataTables_Example.framework; path = "Pods-SwiftDataTables_Example.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; - 9C520E0139094370E530D4155DD50D34 /* SwiftDataTables.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = SwiftDataTables.framework; path = SwiftDataTables.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 9A707D5DA18A0996ADF3231840835908 /* Pods_SwiftDataTables_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SwiftDataTables_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 9C520E0139094370E530D4155DD50D34 /* SwiftDataTables.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwiftDataTables.framework; sourceTree = BUILT_PRODUCTS_DIR; }; A4A7D10DFC80274683FA6D5D7CB30045 /* Pods-SwiftDataTables_Tests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-SwiftDataTables_Tests-dummy.m"; sourceTree = ""; }; A9497FD77AFF9D1079B44445D1536828 /* Pods-SwiftDataTables_Example-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-SwiftDataTables_Example-acknowledgements.markdown"; sourceTree = ""; }; - AE3FA8C289BB2B0213DFCD9351E770DC /* Pods-SwiftDataTables_Tests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; path = "Pods-SwiftDataTables_Tests.modulemap"; sourceTree = ""; }; + AE3FA8C289BB2B0213DFCD9351E770DC /* Pods-SwiftDataTables_Tests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = "Pods-SwiftDataTables_Tests.modulemap"; sourceTree = ""; }; B6B09B046705E533AEAE674DAD999AE2 /* DataStructureModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DataStructureModel.swift; sourceTree = ""; }; B8A3C43C936854AC7B9E3E96FBAFFFB3 /* DataCellRowRepresentable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DataCellRowRepresentable.swift; sourceTree = ""; }; BC0FD0FEE4B07056B1C991A1EC970739 /* Pods-SwiftDataTables_Tests-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-SwiftDataTables_Tests-frameworks.sh"; sourceTree = ""; }; - C51B1CBE13F43FCA0ED53371BD6546BA /* column-sort-unspecified.png */ = {isa = PBXFileReference; includeInIndex = 1; path = "column-sort-unspecified.png"; sourceTree = ""; }; - C5ED1D2C95803E58A72D6699C4F0DC03 /* column-sort-descending.png */ = {isa = PBXFileReference; includeInIndex = 1; path = "column-sort-descending.png"; sourceTree = ""; }; + C51B1CBE13F43FCA0ED53371BD6546BA /* column-sort-unspecified.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = "column-sort-unspecified.png"; sourceTree = ""; }; + C5ED1D2C95803E58A72D6699C4F0DC03 /* column-sort-descending.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = "column-sort-descending.png"; sourceTree = ""; }; CBB3DE36805AF21409EC968A9691732F /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; D2C50F93E3FF19DF9139E95FCA488BA4 /* Pods-SwiftDataTables_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-SwiftDataTables_Tests.debug.xcconfig"; sourceTree = ""; }; D33697A87B8F44DDE9797AA32060CD8B /* PaginationHeaderViewModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = PaginationHeaderViewModel.swift; sourceTree = ""; }; @@ -175,7 +177,6 @@ C5ED1D2C95803E58A72D6699C4F0DC03 /* column-sort-descending.png */, C51B1CBE13F43FCA0ED53371BD6546BA /* column-sort-unspecified.png */, ); - name = SwiftDataTables.bundle; path = SwiftDataTables.bundle; sourceTree = ""; }; @@ -186,7 +187,6 @@ 7DBB33DAE7B794564F6FA560075614C8 /* MenuLengthHeader.xib */, 5FF66442B3706F72C3360B21A22E47D8 /* MenuLengthHeaderViewModel.swift */, ); - name = MenuLengthHeader; path = MenuLengthHeader; sourceTree = ""; }; @@ -195,7 +195,6 @@ children = ( 1AD804FA3D8F3F6364A5D9D007B80856 /* SwiftDataTable+Extensions.swift */, ); - name = Extensions; path = Extensions; sourceTree = ""; }; @@ -243,8 +242,8 @@ 457C12057ABCC332009AA524E13FA70B /* MenuLengthHeader */, E0138C9574692E135E92BA4D19C072BF /* PaginationHeader */, DE208CE36A0B4FC548333CB6E7ED0ED8 /* Protocols */, + 057C454D1E7944B400B3F747 /* DataTableSearchTextField.swift */, ); - name = Classes; path = Classes; sourceTree = ""; }; @@ -297,7 +296,6 @@ 8EE1F7C243C8D194CB6C5DFC46CE2597 /* DataCellLayoutAttributes.swift */, 3CFE8D2B2475153C3B82873CBD1500D5 /* DataCellViewModel.swift */, ); - name = DataCell; path = DataCell; sourceTree = ""; }; @@ -335,7 +333,6 @@ children = ( 7CD548E01AB1C82543F72FC3ACDE740B /* SwiftDataTables.bundle */, ); - name = SwiftDataTables; path = SwiftDataTables; sourceTree = ""; }; @@ -346,7 +343,6 @@ 5FE39D66642A56668EE1C80FE219DEBC /* DataHeaderFooter.xib */, 692C83EA7BDB5F20630C8A087F6D4189 /* DataHeaderFooterViewModel.swift */, ); - name = HeaderFooter; path = HeaderFooter; sourceTree = ""; }; @@ -358,7 +354,6 @@ B8A3C43C936854AC7B9E3E96FBAFFFB3 /* DataCellRowRepresentable.swift */, 09B4FE2CBBA7486FA032F19F7C6EC1D1 /* VirtualPositionTrackable.swift */, ); - name = Protocols; path = Protocols; sourceTree = ""; }; @@ -369,7 +364,6 @@ 70B187106D06C52BCE59600E80CACA8E /* PaginationHeader.xib */, D33697A87B8F44DDE9797AA32060CD8B /* PaginationHeaderViewModel.swift */, ); - name = PaginationHeader; path = PaginationHeader; sourceTree = ""; }; @@ -387,7 +381,6 @@ 7DEF21227A9E0A672F52277BE275EF9E /* Classes */, 3E0D795ABA8D0AA008CF45EBFE23D733 /* SwiftDataTables.bundle */, ); - name = SwiftDataTables; path = SwiftDataTables; sourceTree = ""; }; @@ -482,6 +475,11 @@ attributes = { LastSwiftUpdateCheck = 0730; LastUpgradeCheck = 0700; + TargetAttributes = { + 35A7856F4E4D9B71B975A5AF937288AB = { + LastSwiftMigration = 0820; + }; + }; }; buildConfigurationList = 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */; compatibilityVersion = "Xcode 3.2"; @@ -555,6 +553,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 057C454E1E7944B400B3F747 /* DataTableSearchTextField.swift in Sources */, 04E67A60A59D89EDD0FA3954807BACA2 /* Pods-SwiftDataTables_Example-dummy.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -627,6 +626,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = 77FCE7AAEC3AB0B69D0D0F1E47526A55 /* Pods-SwiftDataTables_Example.debug.xcconfig */; buildSettings = { + CLANG_ENABLE_MODULES = YES; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; @@ -653,6 +653,7 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -770,6 +771,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = 80EFFBC331D7B75C7689F478B728663E /* Pods-SwiftDataTables_Example.release.xcconfig */; buildSettings = { + CLANG_ENABLE_MODULES = YES; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; @@ -795,6 +797,7 @@ PRODUCT_NAME = Pods_SwiftDataTables_Example; SDKROOT = iphoneos; SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; diff --git a/SwiftDataTables/Classes/DataTableSearchTextField.swift b/SwiftDataTables/Classes/DataTableSearchTextField.swift new file mode 100644 index 0000000..1a5e90e --- /dev/null +++ b/SwiftDataTables/Classes/DataTableSearchTextField.swift @@ -0,0 +1,14 @@ +// +// DataTableSearchTextField.swift +// Pods +// +// Created by Pavan Kataria on 15/03/2017. +// +// + +import UIKit + +class DataTableSearchTextField: UITextField { + + +} From a99f44c65c02729ea8aa2cb5cd41c71692cab440 Mon Sep 17 00:00:00 2001 From: Pavan Kataria Date: Wed, 15 Mar 2017 09:49:52 +0000 Subject: [PATCH 02/21] Renamed menu length header to search header for enum type --- Example/Pods/Pods.xcodeproj/project.pbxproj | 6 +++--- SwiftDataTables/Classes/SwiftDataTable.swift | 12 ++++++++---- .../Classes/SwiftDataTableFlowLayout.swift | 6 +++--- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/Example/Pods/Pods.xcodeproj/project.pbxproj b/Example/Pods/Pods.xcodeproj/project.pbxproj index 932ef16..7aa8c22 100644 --- a/Example/Pods/Pods.xcodeproj/project.pbxproj +++ b/Example/Pods/Pods.xcodeproj/project.pbxproj @@ -228,21 +228,21 @@ 7DEF21227A9E0A672F52277BE275EF9E /* Classes */ = { isa = PBXGroup; children = ( + D6E801D8109B27ABF2C29EB0C82DCF8C /* SwiftDataTable.swift */, + DA0A3B002A6F00B48748D52241622DCE /* SwiftDataTableFlowLayout.swift */, + 057C454D1E7944B400B3F747 /* DataTableSearchTextField.swift */, 24C5B75DC8BB1D3AC33E13F348A6FD17 /* DataStore.swift */, B6B09B046705E533AEAE674DAD999AE2 /* DataStructureModel.swift */, 7545976213A79CF058DF04F103DA13F5 /* DataTableConfiguration.swift */, 758C2C1E7462638527091ADC27FBC27E /* DataTableSortable.swift */, FD3A7ED43AABB75248525A0E205BDAE4 /* DataTableSortType.swift */, DA7ECB32F073B7A01296671D9C29E01C /* DataTableValueType.swift */, - D6E801D8109B27ABF2C29EB0C82DCF8C /* SwiftDataTable.swift */, - DA0A3B002A6F00B48748D52241622DCE /* SwiftDataTableFlowLayout.swift */, 9DF386D91D557BC7C32220A418A3580F /* DataCell */, 622366AF1820CF887AB0D17EAA765D1D /* Extensions */, C6E7C30C3C108CF7210E29AF8F74BA51 /* HeaderFooter */, 457C12057ABCC332009AA524E13FA70B /* MenuLengthHeader */, E0138C9574692E135E92BA4D19C072BF /* PaginationHeader */, DE208CE36A0B4FC548333CB6E7ED0ED8 /* Protocols */, - 057C454D1E7944B400B3F747 /* DataTableSearchTextField.swift */, ); path = Classes; sourceTree = ""; diff --git a/SwiftDataTables/Classes/SwiftDataTable.swift b/SwiftDataTables/Classes/SwiftDataTable.swift index ecbb469..0b809d8 100644 --- a/SwiftDataTables/Classes/SwiftDataTable.swift +++ b/SwiftDataTables/Classes/SwiftDataTable.swift @@ -22,7 +22,7 @@ public class SwiftDataTable: UIView { case footerHeader = "SwiftDataTableFooterHeader" /// Single header positioned at the bottom below the footer section. - case menuLengthHeader = "SwiftDataTableMenuLengthHeader" + case searchHeader = "SwiftDataTableMenuLengthHeader" init(kind: String){ guard let elementKind = SupplementaryViewType(rawValue: kind) else { @@ -171,7 +171,7 @@ public class SwiftDataTable: UIView { let menuLengthIdentifier = String(describing: MenuLengthHeader.self) - collectionView.register(UINib(nibName: menuLengthIdentifier, bundle: podBundle), forSupplementaryViewOfKind: SupplementaryViewType.menuLengthHeader.rawValue, withReuseIdentifier: menuLengthIdentifier) + collectionView.register(UINib(nibName: menuLengthIdentifier, bundle: podBundle), forSupplementaryViewOfKind: SupplementaryViewType.searchHeader.rawValue, withReuseIdentifier: menuLengthIdentifier) } func set(data: [[DataTableValueType]], headerTitles: [String], options: DataTableConfiguration? = nil){ @@ -284,7 +284,7 @@ extension SwiftDataTable: UICollectionViewDataSource { public func collectionView(_ collectionView: UICollectionView, willDisplaySupplementaryView view: UICollectionReusableView, forElementKind elementKind: String, at indexPath: IndexPath) { let kind = SupplementaryViewType(kind: elementKind) switch kind { - case .paginationHeader, .menuLengthHeader: + case .paginationHeader, .searchHeader: view.backgroundColor = UIColor.darkGray default: view.backgroundColor = UIColor.white @@ -306,7 +306,7 @@ extension SwiftDataTable: UICollectionViewDataSource { let elementKind = SupplementaryViewType(kind: kind) let viewModel: CollectionViewSupplementaryElementRepresentable switch elementKind { - case .menuLengthHeader: viewModel = self.menuLengthViewModel + case .searchHeader: viewModel = self.menuLengthViewModel case .columnHeader: viewModel = self.headerViewModels[indexPath.index] case .footerHeader: viewModel = self.footerViewModels[indexPath.index] case .paginationHeader: viewModel = self.paginationViewModel @@ -462,10 +462,14 @@ extension SwiftDataTable { return self.dataStructure.footerTitles.count } + func showsSearchBar() -> Bool { + return true + } func shouldContentWidthScaleToFillFrame() -> Bool{ return true } + func shouldSectionHeadersFloat() -> Bool { return true } diff --git a/SwiftDataTables/Classes/SwiftDataTableFlowLayout.swift b/SwiftDataTables/Classes/SwiftDataTableFlowLayout.swift index 75a3392..92a2d49 100644 --- a/SwiftDataTables/Classes/SwiftDataTableFlowLayout.swift +++ b/SwiftDataTables/Classes/SwiftDataTableFlowLayout.swift @@ -107,7 +107,7 @@ class SwiftDataTableFlowLayout: UICollectionViewFlowLayout { if self.dataTable.shouldShowSearchSection(){ let menuLengthIndexPath = IndexPath(index: 0) if let menuLengthAttributes = self.layoutAttributesForSupplementaryView(ofKind: - SwiftDataTable.SupplementaryViewType.menuLengthHeader.rawValue, at: menuLengthIndexPath){ + SwiftDataTable.SupplementaryViewType.searchHeader.rawValue, at: menuLengthIndexPath){ attributes.append(menuLengthAttributes) } } @@ -170,7 +170,7 @@ extension SwiftDataTableFlowLayout { override func layoutAttributesForSupplementaryView(ofKind elementKind: String, at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? { let kind = SwiftDataTable.SupplementaryViewType(kind: elementKind) switch kind { - case .menuLengthHeader: return self.layoutAttributesForMenuLengthView(at: indexPath) + case .searchHeader: return self.layoutAttributesForMenuLengthView(at: indexPath) case .columnHeader: return self.layoutAttributesForColumnHeaderView(at: indexPath) case .footerHeader: return self.layoutAttributesForColumnFooterView(at: indexPath) case .paginationHeader: return self.layoutAttributesForPaginationView(at: indexPath) @@ -179,7 +179,7 @@ extension SwiftDataTableFlowLayout { func layoutAttributesForMenuLengthView(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? { - let attribute = UICollectionViewLayoutAttributes(forSupplementaryViewOfKind: SwiftDataTable.SupplementaryViewType.menuLengthHeader.rawValue, with: indexPath) + let attribute = UICollectionViewLayoutAttributes(forSupplementaryViewOfKind: SwiftDataTable.SupplementaryViewType.searchHeader.rawValue, with: indexPath) let x: CGFloat = self.dataTable.collectionView.contentOffset.x let y: CGFloat = 0 let width = self.dataTable.collectionView.bounds.width From bcc38c58297c7b225b97cb0a912b9d680e2dd148 Mon Sep 17 00:00:00 2001 From: Pavan Kataria Date: Wed, 15 Mar 2017 10:53:40 +0000 Subject: [PATCH 03/21] Implements textfield subclass for search, and customises colour --- Example/Podfile.lock | 4 +- .../SwiftDataTables.podspec.json | 4 +- Example/Pods/Manifest.lock | 4 +- Example/Pods/Pods.xcodeproj/project.pbxproj | 353 +++++++++--------- .../SwiftDataTables/Info.plist | 2 +- .../Classes/DataTableSearchTextField.swift | 37 +- .../MenuLengthHeader/MenuLengthHeader.xib | 17 +- SwiftDataTables/Classes/SwiftDataTable.swift | 14 +- .../Classes/SwiftDataTableFlowLayout.swift | 14 +- 9 files changed, 235 insertions(+), 214 deletions(-) diff --git a/Example/Podfile.lock b/Example/Podfile.lock index 50bb607..8a959e5 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -1,5 +1,5 @@ PODS: - - SwiftDataTables (0.3.0) + - SwiftDataTables (0.3.1) DEPENDENCIES: - SwiftDataTables (from `../`) @@ -9,7 +9,7 @@ EXTERNAL SOURCES: :path: "../" SPEC CHECKSUMS: - SwiftDataTables: bb9323c35a72b0da6acd042721df3c4a07eb1a02 + SwiftDataTables: d1cc6d6b606e7cb57146b429c9cc2a2b3765705b PODFILE CHECKSUM: 117ac710a88fe801ecac2a925baa29b1107fef2e diff --git a/Example/Pods/Local Podspecs/SwiftDataTables.podspec.json b/Example/Pods/Local Podspecs/SwiftDataTables.podspec.json index 5b3d73e..a1c78c3 100644 --- a/Example/Pods/Local Podspecs/SwiftDataTables.podspec.json +++ b/Example/Pods/Local Podspecs/SwiftDataTables.podspec.json @@ -1,6 +1,6 @@ { "name": "SwiftDataTables", - "version": "0.3.0", + "version": "0.3.1", "summary": "A Swift Data Table package that allows ordering, searching, and paging with extensible options.", "description": "SwiftDataTables allows you to display grid-like data sets in a nicely formatted table for iOS. The main goal for the end-user are to be able to obtain useful information from the table as quickly as possible with the following features: ordering, searching, and paging; where as for the developer is to allow for easy implementation with extensible options. This package was inspired by Javascript's DataTables package.", "homepage": "https://github.com/pavankataria/SwiftDataTables", @@ -13,7 +13,7 @@ }, "source": { "git": "https://github.com/pavankataria/SwiftDataTables.git", - "tag": "0.3.0" + "tag": "0.3.1" }, "platforms": { "ios": "8.0" diff --git a/Example/Pods/Manifest.lock b/Example/Pods/Manifest.lock index 50bb607..8a959e5 100644 --- a/Example/Pods/Manifest.lock +++ b/Example/Pods/Manifest.lock @@ -1,5 +1,5 @@ PODS: - - SwiftDataTables (0.3.0) + - SwiftDataTables (0.3.1) DEPENDENCIES: - SwiftDataTables (from `../`) @@ -9,7 +9,7 @@ EXTERNAL SOURCES: :path: "../" SPEC CHECKSUMS: - SwiftDataTables: bb9323c35a72b0da6acd042721df3c4a07eb1a02 + SwiftDataTables: d1cc6d6b606e7cb57146b429c9cc2a2b3765705b PODFILE CHECKSUM: 117ac710a88fe801ecac2a925baa29b1107fef2e diff --git a/Example/Pods/Pods.xcodeproj/project.pbxproj b/Example/Pods/Pods.xcodeproj/project.pbxproj index 7aa8c22..e87a4b7 100644 --- a/Example/Pods/Pods.xcodeproj/project.pbxproj +++ b/Example/Pods/Pods.xcodeproj/project.pbxproj @@ -7,46 +7,46 @@ objects = { /* Begin PBXBuildFile section */ - 04D3A2072D43BBF4D1BFDFD45F859226 /* DataCellLayoutAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EE1F7C243C8D194CB6C5DFC46CE2597 /* DataCellLayoutAttributes.swift */; }; 04E67A60A59D89EDD0FA3954807BACA2 /* Pods-SwiftDataTables_Example-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 384C6C6A4148C520C98D0600D7393727 /* Pods-SwiftDataTables_Example-dummy.m */; }; - 057C454E1E7944B400B3F747 /* DataTableSearchTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 057C454D1E7944B400B3F747 /* DataTableSearchTextField.swift */; }; 081E967D67DC9BED078AAC67DDB50B6A /* SwiftDataTables.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 7CD548E01AB1C82543F72FC3ACDE740B /* SwiftDataTables.bundle */; }; - 0C4C3FD1B0C3881E2A7BA491A0E3CDE7 /* DataHeaderFooter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F51A0022452EF1EFD995A3C901C8035 /* DataHeaderFooter.swift */; }; + 0AC82994E79C72757A7C838A957E514A /* DataTableValueType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EE833874126E5AF2AA48DB3395A88D /* DataTableValueType.swift */; }; + 0E4DA195C1DD249BC36F46704E6479E5 /* DataHeaderFooter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F2BFF8086A7BBEE3511BF1A27D50091 /* DataHeaderFooter.swift */; }; + 0EDC34D3842A179C17600AF096B5FD74 /* DataStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E4C9491808FD1FFE914DCAFAD7D2386 /* DataStore.swift */; }; 13DC5749947421DFD00ECF07EDF28D52 /* SwiftDataTables-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 78A14C8773B4B9CD3ADB324703A6D84D /* SwiftDataTables-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 155AF45595400F755AD7510330CE2E2D /* CollectionViewSupplementaryElementRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D230D9B285E4DB6BE57283D0DA369B9 /* CollectionViewSupplementaryElementRepresentable.swift */; }; + 1682199B9F2387EAB9F0AE264D73BF64 /* DataCellLayoutAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5DBDD794DC94DD50E8634CB2C820BB /* DataCellLayoutAttributes.swift */; }; + 1D5412B8BE164CC40AB37056472738A0 /* column-sort-ascending.png in Sources */ = {isa = PBXBuildFile; fileRef = F1473A9A43EE02DA71DEF3040C95FD04 /* column-sort-ascending.png */; }; + 1FB1428BB6E1A60FD7E3A379816CFF40 /* SwiftDataTableFlowLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DD4E394D6FE142F7550AFFFC101A045 /* SwiftDataTableFlowLayout.swift */; }; + 24F7481937E91176DD274096E22F65B0 /* PaginationHeader.xib in Sources */ = {isa = PBXBuildFile; fileRef = 48CFB127CFA921DC3DCEFF98D9ABE2C4 /* PaginationHeader.xib */; }; + 260D49F616F0784BD9D51B7EB6CDC051 /* PaginationHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1224A3CF41ABF565DE4D754A763937CC /* PaginationHeader.swift */; }; + 27B9153C7A19C109271A4606EFE3E633 /* DataTableSortable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F2E83AB3AB39BF705EE3F1638D6B29F /* DataTableSortable.swift */; }; 292E3B98E782786FCBD6C3F3F53F5507 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CBB3DE36805AF21409EC968A9691732F /* Foundation.framework */; }; - 2AF491F84ACD4C8AFDBC5725149D67BB /* DataTableSortable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 758C2C1E7462638527091ADC27FBC27E /* DataTableSortable.swift */; }; - 2E26B4E84EFC5D6AD20E456938B92982 /* column-sort-descending.png in Sources */ = {isa = PBXBuildFile; fileRef = C5ED1D2C95803E58A72D6699C4F0DC03 /* column-sort-descending.png */; }; - 35BC77868CC47151547D08C4BE923246 /* DataCell.xib in Sources */ = {isa = PBXBuildFile; fileRef = 58396C00E501273D8D517F4680C5497B /* DataCell.xib */; }; - 361C0FD3E09385E01C9851B26F2C61BE /* DataTableValueType.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA7ECB32F073B7A01296671D9C29E01C /* DataTableValueType.swift */; }; - 3C5F558833ACE66DDAD220135719D273 /* SwiftDataTables-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 29529D22A36CCD1CF3C8A3E37CF8AA82 /* SwiftDataTables-dummy.m */; }; - 3C70FA40AE67C09E1DFA28AFC3DCC226 /* DataStructureModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B09B046705E533AEAE674DAD999AE2 /* DataStructureModel.swift */; }; + 2A02F59F62B6257E91B36ABE5DE187E5 /* DataCell.xib in Sources */ = {isa = PBXBuildFile; fileRef = 5445F32930D137199F2797334ADE657C /* DataCell.xib */; }; + 3BFE5A7673FE26C58192AE4A4804FB14 /* column-sort-descending.png in Sources */ = {isa = PBXBuildFile; fileRef = 8010CB43D447228DB2F3EE74CF263D14 /* column-sort-descending.png */; }; 414F302D223415907C50295B635EAACF /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CBB3DE36805AF21409EC968A9691732F /* Foundation.framework */; }; - 5CBA47C5F7B5145795D38A11F28FBC39 /* MenuLengthHeaderViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FF66442B3706F72C3360B21A22E47D8 /* MenuLengthHeaderViewModel.swift */; }; - 62005E546AAD30CC92BAD45F5D788875 /* PaginationHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81A1BB62F579338FB5B3D1B46593C516 /* PaginationHeader.swift */; }; + 447D725629DFA0BD37D78278F9BAA7E9 /* CollectionViewSupplementaryElementRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1A11813CA7C50E41A73FD7F6A7FA1FE /* CollectionViewSupplementaryElementRepresentable.swift */; }; + 4F625F11B00F2A82C79A58683EAE5ED6 /* DataCellViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B2ED54993F40761375E7A5530B7B5F9 /* DataCellViewModel.swift */; }; + 54186B6BB64AA1385130D4CFDF8C1C32 /* DataCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8AF054D142EAEC82F6E543C5EDC8B4D /* DataCell.swift */; }; + 5ADFDE8DC6E446CEB2F64949A4C64807 /* DataCellRowRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4328688BC5F6D3F5EEB1AED82637E62A /* DataCellRowRepresentable.swift */; }; + 604D321EF4346D8126333D5309EABDCE /* MenuLengthHeaderViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B41D17014B3C074EDB0CCD2736C0808 /* MenuLengthHeaderViewModel.swift */; }; 687712BFB353D8BDC08E7CE1F089A761 /* Pods-SwiftDataTables_Example-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 5277C1C4F649828D9CEE62AF4D307B53 /* Pods-SwiftDataTables_Example-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6A754488F2940DEE2BE0B4680D30B830 /* DataTableConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7545976213A79CF058DF04F103DA13F5 /* DataTableConfiguration.swift */; }; - 6BCD50C7C8D2AEFE81B6DC028BD64892 /* DataTableSortType.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD3A7ED43AABB75248525A0E205BDAE4 /* DataTableSortType.swift */; }; - 6D296F7C0DD65616E31298E40A4200C5 /* DataHeaderFooterViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 692C83EA7BDB5F20630C8A087F6D4189 /* DataHeaderFooterViewModel.swift */; }; + 6A05AC585F344B122E7D07F157D73C90 /* VirtualPositionTrackable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E122E61E1C8C49B04CF74BCCFA6161B /* VirtualPositionTrackable.swift */; }; 73ED7945DE34869F021F0ABCDA39FD5D /* Pods-SwiftDataTables_Tests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = A4A7D10DFC80274683FA6D5D7CB30045 /* Pods-SwiftDataTables_Tests-dummy.m */; }; - 7E79D622172995458EE3F96123FBC676 /* VirtualPositionTrackable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09B4FE2CBBA7486FA032F19F7C6EC1D1 /* VirtualPositionTrackable.swift */; }; - 872F4A71132D099AEA08A1EA096F3D4C /* MenuLengthHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC435B597A1AB28EFC1D91289A40A4E6 /* MenuLengthHeader.swift */; }; - 8CD7C202E24196AC12F79C16FF4E6D87 /* column-sort-unspecified.png in Sources */ = {isa = PBXBuildFile; fileRef = C51B1CBE13F43FCA0ED53371BD6546BA /* column-sort-unspecified.png */; }; - 8F4CAE912203890EB984FE7D249E1647 /* column-sort-ascending.png in Sources */ = {isa = PBXBuildFile; fileRef = 5CBE07CBEF0A9F6D1115A9DCD2EEA50C /* column-sort-ascending.png */; }; + 879F2DA5C13B4A0B6D519FF3BEC59C48 /* DataHeaderFooter.xib in Sources */ = {isa = PBXBuildFile; fileRef = A0CF2E9F66B58735D143648B30DF58D4 /* DataHeaderFooter.xib */; }; + 8B9C0C7AC4570DD2E90E213607105E40 /* DataTableConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = B29B0F533FE64494E873A1152A0341C7 /* DataTableConfiguration.swift */; }; + 90EF5F0AEE0C81BA83CB8ADC4AAC9183 /* SwiftDataTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AB3AACE6A2F1AFB21B65E918C6BD945 /* SwiftDataTable.swift */; }; + 9FDCB4FCBE392492BD993DB008E0E331 /* DataHeaderFooterViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 281CBD36BC8026945D142671328F8C7D /* DataHeaderFooterViewModel.swift */; }; + A038ED326D306EF638F005DC25DDC868 /* DataStructureModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19146F6458BB58D305987C6D05D75DDB /* DataStructureModel.swift */; }; + A420CBA695BC6A5D41FDDB3556683361 /* column-sort-unspecified.png in Sources */ = {isa = PBXBuildFile; fileRef = BBACAFE153377B02F371E7CEBE6CFE4D /* column-sort-unspecified.png */; }; A87D6C482F0E32A837FF84052D383EE2 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CBB3DE36805AF21409EC968A9691732F /* Foundation.framework */; }; - AAB0D3BF1DCF998A416345AD0D3FA94A /* DataHeaderFooter.xib in Sources */ = {isa = PBXBuildFile; fileRef = 5FE39D66642A56668EE1C80FE219DEBC /* DataHeaderFooter.xib */; }; - AB8F247AEAD41BB1641A263D940D263C /* MenuLengthHeader.xib in Sources */ = {isa = PBXBuildFile; fileRef = 7DBB33DAE7B794564F6FA560075614C8 /* MenuLengthHeader.xib */; }; - B5FDE273BF516D8426A0002E3CC2DB22 /* SwiftDataTable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AD804FA3D8F3F6364A5D9D007B80856 /* SwiftDataTable+Extensions.swift */; }; - C17B750075715E03B148AC604FAEE825 /* SwiftDataTableFlowLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA0A3B002A6F00B48748D52241622DCE /* SwiftDataTableFlowLayout.swift */; }; + AA38751546A71EEA92F93C1D73090288 /* MenuLengthHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1800F12E1FCB665A56571DAEDFA4A3E2 /* MenuLengthHeader.swift */; }; + ADFAD95B15D0B645F6F6FDEE5A3F87A4 /* PaginationHeaderViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE4EFD0DC1BEDDDE8D0946323DCAF903 /* PaginationHeaderViewModel.swift */; }; C18134F7C0F58091AC9EA05ECEA44E6F /* Pods-SwiftDataTables_Tests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 3CC4698961C3BFC187A9932973FDBA01 /* Pods-SwiftDataTables_Tests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - C26D4DCB949EAFBCCAE561F9F62A736B /* PaginationHeader.xib in Sources */ = {isa = PBXBuildFile; fileRef = 70B187106D06C52BCE59600E80CACA8E /* PaginationHeader.xib */; }; - C69882855206EA713FE1C6427851B34C /* DataStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24C5B75DC8BB1D3AC33E13F348A6FD17 /* DataStore.swift */; }; - C864273AF5D17F7176186DAFEF19AB3D /* PaginationHeaderViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D33697A87B8F44DDE9797AA32060CD8B /* PaginationHeaderViewModel.swift */; }; - DE23705BA788F762AEC564940DC5B258 /* DataCellViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CFE8D2B2475153C3B82873CBD1500D5 /* DataCellViewModel.swift */; }; - FB1A49A5265FEF672D6190A5D46A937C /* CollectionViewCellRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F5F6B5F09B6B3170BEF01CA41B2823A /* CollectionViewCellRepresentable.swift */; }; - FC2A9D3708B5820E0C0304E5EF1C14CD /* DataCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96CB8888EBCDDEA599EB73C4DB608B5A /* DataCell.swift */; }; - FD73735DACD60D5B0A36E1A9CD3F8A0B /* DataCellRowRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8A3C43C936854AC7B9E3E96FBAFFFB3 /* DataCellRowRepresentable.swift */; }; - FFAF529B34E378B0F1BA092DB2768A50 /* SwiftDataTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E801D8109B27ABF2C29EB0C82DCF8C /* SwiftDataTable.swift */; }; + C4F12AAD947E94A55DAE928D29577396 /* DataTableSearchTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34D9B4AA17DB4832284C840A91D56FB0 /* DataTableSearchTextField.swift */; }; + CACC1A90A6AE7ED12653C4E1E6335A2F /* DataTableSortType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D90D3D7ADBC49A31D8FEB1F60C052DE9 /* DataTableSortType.swift */; }; + CE4A90BF76D93DFCC04D3DCE233D3657 /* CollectionViewCellRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 915E0818C20643221F40E1DD18875ABB /* CollectionViewCellRepresentable.swift */; }; + D3358DC10F15C090C59F1B46BCC5AFE4 /* SwiftDataTable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB0D9A758F5D07A5B156C972F7EC6C73 /* SwiftDataTable+Extensions.swift */; }; + E5B9CC9B9DB447A50C0720093EC0D21E /* SwiftDataTables-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 29529D22A36CCD1CF3C8A3E37CF8AA82 /* SwiftDataTables-dummy.m */; }; + FA72CBA68B50E5EBDCD25648C81BA9AA /* MenuLengthHeader.xib in Sources */ = {isa = PBXBuildFile; fileRef = 61FDDE21982EEE8A070F64045882C0AF /* MenuLengthHeader.xib */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -61,67 +61,67 @@ /* Begin PBXFileReference section */ 026CC3068F40BE2D05647A2410B36B3B /* Pods-SwiftDataTables_Tests-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-SwiftDataTables_Tests-resources.sh"; sourceTree = ""; }; - 057C454D1E7944B400B3F747 /* DataTableSearchTextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataTableSearchTextField.swift; sourceTree = ""; }; - 09B4FE2CBBA7486FA032F19F7C6EC1D1 /* VirtualPositionTrackable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = VirtualPositionTrackable.swift; sourceTree = ""; }; + 0E4C9491808FD1FFE914DCAFAD7D2386 /* DataStore.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DataStore.swift; sourceTree = ""; }; 1037553484562CE309A3013538712A90 /* Pods_SwiftDataTables_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SwiftDataTables_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 1224A3CF41ABF565DE4D754A763937CC /* PaginationHeader.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = PaginationHeader.swift; sourceTree = ""; }; 15D74D4F308C07A9FF50DFDA2A0736D9 /* Pods-SwiftDataTables_Example.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = "Pods-SwiftDataTables_Example.modulemap"; sourceTree = ""; }; + 1800F12E1FCB665A56571DAEDFA4A3E2 /* MenuLengthHeader.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = MenuLengthHeader.swift; sourceTree = ""; }; 18B3638F5AD13E6EBCB7FBA837D1D5AD /* Pods-SwiftDataTables_Tests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-SwiftDataTables_Tests-acknowledgements.markdown"; sourceTree = ""; }; - 1AD804FA3D8F3F6364A5D9D007B80856 /* SwiftDataTable+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "SwiftDataTable+Extensions.swift"; sourceTree = ""; }; - 24C5B75DC8BB1D3AC33E13F348A6FD17 /* DataStore.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DataStore.swift; sourceTree = ""; }; + 19146F6458BB58D305987C6D05D75DDB /* DataStructureModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DataStructureModel.swift; sourceTree = ""; }; + 281CBD36BC8026945D142671328F8C7D /* DataHeaderFooterViewModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DataHeaderFooterViewModel.swift; sourceTree = ""; }; 29529D22A36CCD1CF3C8A3E37CF8AA82 /* SwiftDataTables-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SwiftDataTables-dummy.m"; sourceTree = ""; }; 33462704076851C1B758B976F53B9A0C /* Pods-SwiftDataTables_Example-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-SwiftDataTables_Example-frameworks.sh"; sourceTree = ""; }; + 34D9B4AA17DB4832284C840A91D56FB0 /* DataTableSearchTextField.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DataTableSearchTextField.swift; sourceTree = ""; }; 384C6C6A4148C520C98D0600D7393727 /* Pods-SwiftDataTables_Example-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-SwiftDataTables_Example-dummy.m"; sourceTree = ""; }; 396D3B52F501B58F711A7301DAD62C34 /* SwiftDataTables-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftDataTables-prefix.pch"; sourceTree = ""; }; 3CC4698961C3BFC187A9932973FDBA01 /* Pods-SwiftDataTables_Tests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-SwiftDataTables_Tests-umbrella.h"; sourceTree = ""; }; - 3CFE8D2B2475153C3B82873CBD1500D5 /* DataCellViewModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DataCellViewModel.swift; sourceTree = ""; }; - 3D230D9B285E4DB6BE57283D0DA369B9 /* CollectionViewSupplementaryElementRepresentable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CollectionViewSupplementaryElementRepresentable.swift; sourceTree = ""; }; - 3F51A0022452EF1EFD995A3C901C8035 /* DataHeaderFooter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DataHeaderFooter.swift; sourceTree = ""; }; 3FCF927BF691F6711D8A34DA24DE0727 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 4328688BC5F6D3F5EEB1AED82637E62A /* DataCellRowRepresentable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DataCellRowRepresentable.swift; sourceTree = ""; }; + 48CFB127CFA921DC3DCEFF98D9ABE2C4 /* PaginationHeader.xib */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file.xib; path = PaginationHeader.xib; sourceTree = ""; }; 4A7A00092F7F68FE9EB3EDD8772E3635 /* SwiftDataTables.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = SwiftDataTables.modulemap; sourceTree = ""; }; 4AF636A6C261B4B22000184FC87CE66A /* Pods-SwiftDataTables_Example-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-SwiftDataTables_Example-resources.sh"; sourceTree = ""; }; 5277C1C4F649828D9CEE62AF4D307B53 /* Pods-SwiftDataTables_Example-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-SwiftDataTables_Example-umbrella.h"; sourceTree = ""; }; - 58396C00E501273D8D517F4680C5497B /* DataCell.xib */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file.xib; path = DataCell.xib; sourceTree = ""; }; - 5CBE07CBEF0A9F6D1115A9DCD2EEA50C /* column-sort-ascending.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = "column-sort-ascending.png"; sourceTree = ""; }; - 5FE39D66642A56668EE1C80FE219DEBC /* DataHeaderFooter.xib */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file.xib; path = DataHeaderFooter.xib; sourceTree = ""; }; - 5FF66442B3706F72C3360B21A22E47D8 /* MenuLengthHeaderViewModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = MenuLengthHeaderViewModel.swift; sourceTree = ""; }; - 692C83EA7BDB5F20630C8A087F6D4189 /* DataHeaderFooterViewModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DataHeaderFooterViewModel.swift; sourceTree = ""; }; - 6F5F6B5F09B6B3170BEF01CA41B2823A /* CollectionViewCellRepresentable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CollectionViewCellRepresentable.swift; sourceTree = ""; }; - 70B187106D06C52BCE59600E80CACA8E /* PaginationHeader.xib */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file.xib; path = PaginationHeader.xib; sourceTree = ""; }; + 5445F32930D137199F2797334ADE657C /* DataCell.xib */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file.xib; path = DataCell.xib; sourceTree = ""; }; + 5B41D17014B3C074EDB0CCD2736C0808 /* MenuLengthHeaderViewModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = MenuLengthHeaderViewModel.swift; sourceTree = ""; }; + 5DD4E394D6FE142F7550AFFFC101A045 /* SwiftDataTableFlowLayout.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = SwiftDataTableFlowLayout.swift; sourceTree = ""; }; + 61FDDE21982EEE8A070F64045882C0AF /* MenuLengthHeader.xib */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file.xib; path = MenuLengthHeader.xib; sourceTree = ""; }; + 6E122E61E1C8C49B04CF74BCCFA6161B /* VirtualPositionTrackable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = VirtualPositionTrackable.swift; sourceTree = ""; }; 73E22285CF26946E7AD06B00512B3C37 /* SwiftDataTables.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftDataTables.xcconfig; sourceTree = ""; }; - 7545976213A79CF058DF04F103DA13F5 /* DataTableConfiguration.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DataTableConfiguration.swift; sourceTree = ""; }; - 758C2C1E7462638527091ADC27FBC27E /* DataTableSortable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DataTableSortable.swift; sourceTree = ""; }; 77FCE7AAEC3AB0B69D0D0F1E47526A55 /* Pods-SwiftDataTables_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-SwiftDataTables_Example.debug.xcconfig"; sourceTree = ""; }; 78A14C8773B4B9CD3ADB324703A6D84D /* SwiftDataTables-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftDataTables-umbrella.h"; sourceTree = ""; }; + 7AB3AACE6A2F1AFB21B65E918C6BD945 /* SwiftDataTable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = SwiftDataTable.swift; sourceTree = ""; }; + 7B5DBDD794DC94DD50E8634CB2C820BB /* DataCellLayoutAttributes.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DataCellLayoutAttributes.swift; sourceTree = ""; }; 7CD548E01AB1C82543F72FC3ACDE740B /* SwiftDataTables.bundle */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "wrapper.plug-in"; path = SwiftDataTables.bundle; sourceTree = ""; }; - 7DBB33DAE7B794564F6FA560075614C8 /* MenuLengthHeader.xib */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file.xib; path = MenuLengthHeader.xib; sourceTree = ""; }; + 8010CB43D447228DB2F3EE74CF263D14 /* column-sort-descending.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = "column-sort-descending.png"; sourceTree = ""; }; 80EFFBC331D7B75C7689F478B728663E /* Pods-SwiftDataTables_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-SwiftDataTables_Example.release.xcconfig"; sourceTree = ""; }; - 81A1BB62F579338FB5B3D1B46593C516 /* PaginationHeader.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = PaginationHeader.swift; sourceTree = ""; }; 86C31390A6D99B60A5D28F7BF13FB249 /* Pods-SwiftDataTables_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-SwiftDataTables_Tests.release.xcconfig"; sourceTree = ""; }; 86FA0E63F942A371F612D17FC46F527F /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 8EE1F7C243C8D194CB6C5DFC46CE2597 /* DataCellLayoutAttributes.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DataCellLayoutAttributes.swift; sourceTree = ""; }; + 8F2BFF8086A7BBEE3511BF1A27D50091 /* DataHeaderFooter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DataHeaderFooter.swift; sourceTree = ""; }; + 915E0818C20643221F40E1DD18875ABB /* CollectionViewCellRepresentable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CollectionViewCellRepresentable.swift; sourceTree = ""; }; 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; - 96CB8888EBCDDEA599EB73C4DB608B5A /* DataCell.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DataCell.swift; sourceTree = ""; }; 9A707D5DA18A0996ADF3231840835908 /* Pods_SwiftDataTables_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SwiftDataTables_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 9B2ED54993F40761375E7A5530B7B5F9 /* DataCellViewModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DataCellViewModel.swift; sourceTree = ""; }; 9C520E0139094370E530D4155DD50D34 /* SwiftDataTables.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwiftDataTables.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 9F2E83AB3AB39BF705EE3F1638D6B29F /* DataTableSortable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DataTableSortable.swift; sourceTree = ""; }; + A0CF2E9F66B58735D143648B30DF58D4 /* DataHeaderFooter.xib */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file.xib; path = DataHeaderFooter.xib; sourceTree = ""; }; A4A7D10DFC80274683FA6D5D7CB30045 /* Pods-SwiftDataTables_Tests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-SwiftDataTables_Tests-dummy.m"; sourceTree = ""; }; + A8AF054D142EAEC82F6E543C5EDC8B4D /* DataCell.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DataCell.swift; sourceTree = ""; }; A9497FD77AFF9D1079B44445D1536828 /* Pods-SwiftDataTables_Example-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-SwiftDataTables_Example-acknowledgements.markdown"; sourceTree = ""; }; AE3FA8C289BB2B0213DFCD9351E770DC /* Pods-SwiftDataTables_Tests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = "Pods-SwiftDataTables_Tests.modulemap"; sourceTree = ""; }; - B6B09B046705E533AEAE674DAD999AE2 /* DataStructureModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DataStructureModel.swift; sourceTree = ""; }; - B8A3C43C936854AC7B9E3E96FBAFFFB3 /* DataCellRowRepresentable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DataCellRowRepresentable.swift; sourceTree = ""; }; + B29B0F533FE64494E873A1152A0341C7 /* DataTableConfiguration.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DataTableConfiguration.swift; sourceTree = ""; }; + BB0D9A758F5D07A5B156C972F7EC6C73 /* SwiftDataTable+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "SwiftDataTable+Extensions.swift"; sourceTree = ""; }; + BBACAFE153377B02F371E7CEBE6CFE4D /* column-sort-unspecified.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = "column-sort-unspecified.png"; sourceTree = ""; }; BC0FD0FEE4B07056B1C991A1EC970739 /* Pods-SwiftDataTables_Tests-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-SwiftDataTables_Tests-frameworks.sh"; sourceTree = ""; }; - C51B1CBE13F43FCA0ED53371BD6546BA /* column-sort-unspecified.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = "column-sort-unspecified.png"; sourceTree = ""; }; - C5ED1D2C95803E58A72D6699C4F0DC03 /* column-sort-descending.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = "column-sort-descending.png"; sourceTree = ""; }; + BE4EFD0DC1BEDDDE8D0946323DCAF903 /* PaginationHeaderViewModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = PaginationHeaderViewModel.swift; sourceTree = ""; }; + C4EE833874126E5AF2AA48DB3395A88D /* DataTableValueType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DataTableValueType.swift; sourceTree = ""; }; CBB3DE36805AF21409EC968A9691732F /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; D2C50F93E3FF19DF9139E95FCA488BA4 /* Pods-SwiftDataTables_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-SwiftDataTables_Tests.debug.xcconfig"; sourceTree = ""; }; - D33697A87B8F44DDE9797AA32060CD8B /* PaginationHeaderViewModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = PaginationHeaderViewModel.swift; sourceTree = ""; }; - D6E801D8109B27ABF2C29EB0C82DCF8C /* SwiftDataTable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = SwiftDataTable.swift; sourceTree = ""; }; - DA0A3B002A6F00B48748D52241622DCE /* SwiftDataTableFlowLayout.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = SwiftDataTableFlowLayout.swift; sourceTree = ""; }; - DA7ECB32F073B7A01296671D9C29E01C /* DataTableValueType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DataTableValueType.swift; sourceTree = ""; }; + D90D3D7ADBC49A31D8FEB1F60C052DE9 /* DataTableSortType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DataTableSortType.swift; sourceTree = ""; }; DB26733A19DEE294A032B66575C90AEA /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - DC435B597A1AB28EFC1D91289A40A4E6 /* MenuLengthHeader.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = MenuLengthHeader.swift; sourceTree = ""; }; + E1A11813CA7C50E41A73FD7F6A7FA1FE /* CollectionViewSupplementaryElementRepresentable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CollectionViewSupplementaryElementRepresentable.swift; sourceTree = ""; }; EC083CA7691E49596D895262F66C5B93 /* Pods-SwiftDataTables_Tests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-SwiftDataTables_Tests-acknowledgements.plist"; sourceTree = ""; }; + F1473A9A43EE02DA71DEF3040C95FD04 /* column-sort-ascending.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = "column-sort-ascending.png"; sourceTree = ""; }; F1E6C461F1C5604D58CFD9E8581D3A94 /* Pods-SwiftDataTables_Example-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-SwiftDataTables_Example-acknowledgements.plist"; sourceTree = ""; }; - FD3A7ED43AABB75248525A0E205BDAE4 /* DataTableSortType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DataTableSortType.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -170,32 +170,54 @@ path = "Target Support Files/Pods-SwiftDataTables_Example"; sourceTree = ""; }; - 3E0D795ABA8D0AA008CF45EBFE23D733 /* SwiftDataTables.bundle */ = { + 2F990587AC3B986CB654E8FC27082921 /* MenuLengthHeader */ = { isa = PBXGroup; children = ( - 5CBE07CBEF0A9F6D1115A9DCD2EEA50C /* column-sort-ascending.png */, - C5ED1D2C95803E58A72D6699C4F0DC03 /* column-sort-descending.png */, - C51B1CBE13F43FCA0ED53371BD6546BA /* column-sort-unspecified.png */, + 1800F12E1FCB665A56571DAEDFA4A3E2 /* MenuLengthHeader.swift */, + 61FDDE21982EEE8A070F64045882C0AF /* MenuLengthHeader.xib */, + 5B41D17014B3C074EDB0CCD2736C0808 /* MenuLengthHeaderViewModel.swift */, + ); + path = MenuLengthHeader; + sourceTree = ""; + }; + 3306E6F17987221B42826806A851A923 /* SwiftDataTables.bundle */ = { + isa = PBXGroup; + children = ( + F1473A9A43EE02DA71DEF3040C95FD04 /* column-sort-ascending.png */, + 8010CB43D447228DB2F3EE74CF263D14 /* column-sort-descending.png */, + BBACAFE153377B02F371E7CEBE6CFE4D /* column-sort-unspecified.png */, ); path = SwiftDataTables.bundle; sourceTree = ""; }; - 457C12057ABCC332009AA524E13FA70B /* MenuLengthHeader */ = { + 4FA2D830EA5AA49F6FB259C295644814 /* SwiftDataTables */ = { isa = PBXGroup; children = ( - DC435B597A1AB28EFC1D91289A40A4E6 /* MenuLengthHeader.swift */, - 7DBB33DAE7B794564F6FA560075614C8 /* MenuLengthHeader.xib */, - 5FF66442B3706F72C3360B21A22E47D8 /* MenuLengthHeaderViewModel.swift */, + 90FCC83B0EA68CB1DD52EBBA8CCA3531 /* Classes */, + 3306E6F17987221B42826806A851A923 /* SwiftDataTables.bundle */, ); - path = MenuLengthHeader; + path = SwiftDataTables; sourceTree = ""; }; - 622366AF1820CF887AB0D17EAA765D1D /* Extensions */ = { + 5F088D4B8E77F214E91F82169E5DF9FE /* PaginationHeader */ = { isa = PBXGroup; children = ( - 1AD804FA3D8F3F6364A5D9D007B80856 /* SwiftDataTable+Extensions.swift */, + 1224A3CF41ABF565DE4D754A763937CC /* PaginationHeader.swift */, + 48CFB127CFA921DC3DCEFF98D9ABE2C4 /* PaginationHeader.xib */, + BE4EFD0DC1BEDDDE8D0946323DCAF903 /* PaginationHeaderViewModel.swift */, ); - path = Extensions; + path = PaginationHeader; + sourceTree = ""; + }; + 5FBD99A5DED4570C24F2FF9C7839B0F5 /* DataCell */ = { + isa = PBXGroup; + children = ( + A8AF054D142EAEC82F6E543C5EDC8B4D /* DataCell.swift */, + 5445F32930D137199F2797334ADE657C /* DataCell.xib */, + 7B5DBDD794DC94DD50E8634CB2C820BB /* DataCellLayoutAttributes.swift */, + 9B2ED54993F40761375E7A5530B7B5F9 /* DataCellViewModel.swift */, + ); + path = DataCell; sourceTree = ""; }; 6F3829022BF39FC6AAF751676A132072 /* Resources */ = { @@ -206,6 +228,17 @@ name = Resources; sourceTree = ""; }; + 6FC49C523238F040A13CC3F0707EA125 /* Protocols */ = { + isa = PBXGroup; + children = ( + 915E0818C20643221F40E1DD18875ABB /* CollectionViewCellRepresentable.swift */, + E1A11813CA7C50E41A73FD7F6A7FA1FE /* CollectionViewSupplementaryElementRepresentable.swift */, + 4328688BC5F6D3F5EEB1AED82637E62A /* DataCellRowRepresentable.swift */, + 6E122E61E1C8C49B04CF74BCCFA6161B /* VirtualPositionTrackable.swift */, + ); + path = Protocols; + sourceTree = ""; + }; 7531C8F8DE19F1AA3C8A7AC97A91DC29 /* iOS */ = { isa = PBXGroup; children = ( @@ -225,35 +258,35 @@ ); sourceTree = ""; }; - 7DEF21227A9E0A672F52277BE275EF9E /* Classes */ = { + 8558C28D56B0F1833537529A4873189A /* Targets Support Files */ = { isa = PBXGroup; children = ( - D6E801D8109B27ABF2C29EB0C82DCF8C /* SwiftDataTable.swift */, - DA0A3B002A6F00B48748D52241622DCE /* SwiftDataTableFlowLayout.swift */, - 057C454D1E7944B400B3F747 /* DataTableSearchTextField.swift */, - 24C5B75DC8BB1D3AC33E13F348A6FD17 /* DataStore.swift */, - B6B09B046705E533AEAE674DAD999AE2 /* DataStructureModel.swift */, - 7545976213A79CF058DF04F103DA13F5 /* DataTableConfiguration.swift */, - 758C2C1E7462638527091ADC27FBC27E /* DataTableSortable.swift */, - FD3A7ED43AABB75248525A0E205BDAE4 /* DataTableSortType.swift */, - DA7ECB32F073B7A01296671D9C29E01C /* DataTableValueType.swift */, - 9DF386D91D557BC7C32220A418A3580F /* DataCell */, - 622366AF1820CF887AB0D17EAA765D1D /* Extensions */, - C6E7C30C3C108CF7210E29AF8F74BA51 /* HeaderFooter */, - 457C12057ABCC332009AA524E13FA70B /* MenuLengthHeader */, - E0138C9574692E135E92BA4D19C072BF /* PaginationHeader */, - DE208CE36A0B4FC548333CB6E7ED0ED8 /* Protocols */, + 27FAFA31EB9F7BE9BAEA050F02406DCD /* Pods-SwiftDataTables_Example */, + 9654D02CE6516AA89ECAC06B710F7969 /* Pods-SwiftDataTables_Tests */, ); - path = Classes; + name = "Targets Support Files"; sourceTree = ""; }; - 8558C28D56B0F1833537529A4873189A /* Targets Support Files */ = { + 90FCC83B0EA68CB1DD52EBBA8CCA3531 /* Classes */ = { isa = PBXGroup; children = ( - 27FAFA31EB9F7BE9BAEA050F02406DCD /* Pods-SwiftDataTables_Example */, - 9654D02CE6516AA89ECAC06B710F7969 /* Pods-SwiftDataTables_Tests */, + 34D9B4AA17DB4832284C840A91D56FB0 /* DataTableSearchTextField.swift */, + 5DD4E394D6FE142F7550AFFFC101A045 /* SwiftDataTableFlowLayout.swift */, + 0E4C9491808FD1FFE914DCAFAD7D2386 /* DataStore.swift */, + 19146F6458BB58D305987C6D05D75DDB /* DataStructureModel.swift */, + B29B0F533FE64494E873A1152A0341C7 /* DataTableConfiguration.swift */, + 9F2E83AB3AB39BF705EE3F1638D6B29F /* DataTableSortable.swift */, + D90D3D7ADBC49A31D8FEB1F60C052DE9 /* DataTableSortType.swift */, + C4EE833874126E5AF2AA48DB3395A88D /* DataTableValueType.swift */, + 7AB3AACE6A2F1AFB21B65E918C6BD945 /* SwiftDataTable.swift */, + 5FBD99A5DED4570C24F2FF9C7839B0F5 /* DataCell */, + ADFF8D727187B584BF991FCDDAFC19E9 /* Extensions */, + CA8C5D9264EAB22AAB22F465425BC725 /* HeaderFooter */, + 2F990587AC3B986CB654E8FC27082921 /* MenuLengthHeader */, + 5F088D4B8E77F214E91F82169E5DF9FE /* PaginationHeader */, + 6FC49C523238F040A13CC3F0707EA125 /* Protocols */, ); - name = "Targets Support Files"; + path = Classes; sourceTree = ""; }; 91F49031BEC3D2C49579FAEEDB8B6C71 /* Support Files */ = { @@ -288,15 +321,12 @@ path = "Target Support Files/Pods-SwiftDataTables_Tests"; sourceTree = ""; }; - 9DF386D91D557BC7C32220A418A3580F /* DataCell */ = { + ADFF8D727187B584BF991FCDDAFC19E9 /* Extensions */ = { isa = PBXGroup; children = ( - 96CB8888EBCDDEA599EB73C4DB608B5A /* DataCell.swift */, - 58396C00E501273D8D517F4680C5497B /* DataCell.xib */, - 8EE1F7C243C8D194CB6C5DFC46CE2597 /* DataCellLayoutAttributes.swift */, - 3CFE8D2B2475153C3B82873CBD1500D5 /* DataCellViewModel.swift */, + BB0D9A758F5D07A5B156C972F7EC6C73 /* SwiftDataTable+Extensions.swift */, ); - path = DataCell; + path = Extensions; sourceTree = ""; }; B7171DEBFA788BC102839F52AEBCD24D /* SwiftDataTables */ = { @@ -304,7 +334,7 @@ children = ( 6F3829022BF39FC6AAF751676A132072 /* Resources */, 91F49031BEC3D2C49579FAEEDB8B6C71 /* Support Files */, - EF49D79784EACE3A2D8180D71361BD1D /* SwiftDataTables */, + 4FA2D830EA5AA49F6FB259C295644814 /* SwiftDataTables */, ); name = SwiftDataTables; path = ../..; @@ -336,37 +366,16 @@ path = SwiftDataTables; sourceTree = ""; }; - C6E7C30C3C108CF7210E29AF8F74BA51 /* HeaderFooter */ = { + CA8C5D9264EAB22AAB22F465425BC725 /* HeaderFooter */ = { isa = PBXGroup; children = ( - 3F51A0022452EF1EFD995A3C901C8035 /* DataHeaderFooter.swift */, - 5FE39D66642A56668EE1C80FE219DEBC /* DataHeaderFooter.xib */, - 692C83EA7BDB5F20630C8A087F6D4189 /* DataHeaderFooterViewModel.swift */, + 8F2BFF8086A7BBEE3511BF1A27D50091 /* DataHeaderFooter.swift */, + A0CF2E9F66B58735D143648B30DF58D4 /* DataHeaderFooter.xib */, + 281CBD36BC8026945D142671328F8C7D /* DataHeaderFooterViewModel.swift */, ); path = HeaderFooter; sourceTree = ""; }; - DE208CE36A0B4FC548333CB6E7ED0ED8 /* Protocols */ = { - isa = PBXGroup; - children = ( - 6F5F6B5F09B6B3170BEF01CA41B2823A /* CollectionViewCellRepresentable.swift */, - 3D230D9B285E4DB6BE57283D0DA369B9 /* CollectionViewSupplementaryElementRepresentable.swift */, - B8A3C43C936854AC7B9E3E96FBAFFFB3 /* DataCellRowRepresentable.swift */, - 09B4FE2CBBA7486FA032F19F7C6EC1D1 /* VirtualPositionTrackable.swift */, - ); - path = Protocols; - sourceTree = ""; - }; - E0138C9574692E135E92BA4D19C072BF /* PaginationHeader */ = { - isa = PBXGroup; - children = ( - 81A1BB62F579338FB5B3D1B46593C516 /* PaginationHeader.swift */, - 70B187106D06C52BCE59600E80CACA8E /* PaginationHeader.xib */, - D33697A87B8F44DDE9797AA32060CD8B /* PaginationHeaderViewModel.swift */, - ); - path = PaginationHeader; - sourceTree = ""; - }; EEF66512A6A08E618028B0E9655A87E5 /* Development Pods */ = { isa = PBXGroup; children = ( @@ -375,15 +384,6 @@ name = "Development Pods"; sourceTree = ""; }; - EF49D79784EACE3A2D8180D71361BD1D /* SwiftDataTables */ = { - isa = PBXGroup; - children = ( - 7DEF21227A9E0A672F52277BE275EF9E /* Classes */, - 3E0D795ABA8D0AA008CF45EBFE23D733 /* SwiftDataTables.bundle */, - ); - path = SwiftDataTables; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -453,7 +453,7 @@ isa = PBXNativeTarget; buildConfigurationList = E37FE4BE49E660A00455BBA146E635D8 /* Build configuration list for PBXNativeTarget "SwiftDataTables" */; buildPhases = ( - 2157F92E17631A4C1CA868A796384A80 /* Sources */, + CAEB5397CC474D90720E2777964FD0E9 /* Sources */, 5203177A10482D5BE9424CDDB4F41031 /* Frameworks */, FFFB985261598D8E39F3C5288C548319 /* Resources */, 2088B95A042860FA554F033730639BCD /* Headers */, @@ -475,11 +475,6 @@ attributes = { LastSwiftUpdateCheck = 0730; LastUpgradeCheck = 0700; - TargetAttributes = { - 35A7856F4E4D9B71B975A5AF937288AB = { - LastSwiftMigration = 0820; - }; - }; }; buildConfigurationList = 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */; compatibilityVersion = "Xcode 3.2"; @@ -512,57 +507,57 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ - 2157F92E17631A4C1CA868A796384A80 /* Sources */ = { + 46258EB914A04B92B0685814CDFADF4B /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - FB1A49A5265FEF672D6190A5D46A937C /* CollectionViewCellRepresentable.swift in Sources */, - 155AF45595400F755AD7510330CE2E2D /* CollectionViewSupplementaryElementRepresentable.swift in Sources */, - 8F4CAE912203890EB984FE7D249E1647 /* column-sort-ascending.png in Sources */, - 2E26B4E84EFC5D6AD20E456938B92982 /* column-sort-descending.png in Sources */, - 8CD7C202E24196AC12F79C16FF4E6D87 /* column-sort-unspecified.png in Sources */, - FC2A9D3708B5820E0C0304E5EF1C14CD /* DataCell.swift in Sources */, - 35BC77868CC47151547D08C4BE923246 /* DataCell.xib in Sources */, - 04D3A2072D43BBF4D1BFDFD45F859226 /* DataCellLayoutAttributes.swift in Sources */, - FD73735DACD60D5B0A36E1A9CD3F8A0B /* DataCellRowRepresentable.swift in Sources */, - DE23705BA788F762AEC564940DC5B258 /* DataCellViewModel.swift in Sources */, - 0C4C3FD1B0C3881E2A7BA491A0E3CDE7 /* DataHeaderFooter.swift in Sources */, - AAB0D3BF1DCF998A416345AD0D3FA94A /* DataHeaderFooter.xib in Sources */, - 6D296F7C0DD65616E31298E40A4200C5 /* DataHeaderFooterViewModel.swift in Sources */, - C69882855206EA713FE1C6427851B34C /* DataStore.swift in Sources */, - 3C70FA40AE67C09E1DFA28AFC3DCC226 /* DataStructureModel.swift in Sources */, - 6A754488F2940DEE2BE0B4680D30B830 /* DataTableConfiguration.swift in Sources */, - 2AF491F84ACD4C8AFDBC5725149D67BB /* DataTableSortable.swift in Sources */, - 6BCD50C7C8D2AEFE81B6DC028BD64892 /* DataTableSortType.swift in Sources */, - 361C0FD3E09385E01C9851B26F2C61BE /* DataTableValueType.swift in Sources */, - 872F4A71132D099AEA08A1EA096F3D4C /* MenuLengthHeader.swift in Sources */, - AB8F247AEAD41BB1641A263D940D263C /* MenuLengthHeader.xib in Sources */, - 5CBA47C5F7B5145795D38A11F28FBC39 /* MenuLengthHeaderViewModel.swift in Sources */, - 62005E546AAD30CC92BAD45F5D788875 /* PaginationHeader.swift in Sources */, - C26D4DCB949EAFBCCAE561F9F62A736B /* PaginationHeader.xib in Sources */, - C864273AF5D17F7176186DAFEF19AB3D /* PaginationHeaderViewModel.swift in Sources */, - B5FDE273BF516D8426A0002E3CC2DB22 /* SwiftDataTable+Extensions.swift in Sources */, - FFAF529B34E378B0F1BA092DB2768A50 /* SwiftDataTable.swift in Sources */, - C17B750075715E03B148AC604FAEE825 /* SwiftDataTableFlowLayout.swift in Sources */, - 3C5F558833ACE66DDAD220135719D273 /* SwiftDataTables-dummy.m in Sources */, - 7E79D622172995458EE3F96123FBC676 /* VirtualPositionTrackable.swift in Sources */, + 04E67A60A59D89EDD0FA3954807BACA2 /* Pods-SwiftDataTables_Example-dummy.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 46258EB914A04B92B0685814CDFADF4B /* Sources */ = { + 849F698359BE4B14AF150EDAC81CF855 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 057C454E1E7944B400B3F747 /* DataTableSearchTextField.swift in Sources */, - 04E67A60A59D89EDD0FA3954807BACA2 /* Pods-SwiftDataTables_Example-dummy.m in Sources */, + 73ED7945DE34869F021F0ABCDA39FD5D /* Pods-SwiftDataTables_Tests-dummy.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 849F698359BE4B14AF150EDAC81CF855 /* Sources */ = { + CAEB5397CC474D90720E2777964FD0E9 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 73ED7945DE34869F021F0ABCDA39FD5D /* Pods-SwiftDataTables_Tests-dummy.m in Sources */, + CE4A90BF76D93DFCC04D3DCE233D3657 /* CollectionViewCellRepresentable.swift in Sources */, + 447D725629DFA0BD37D78278F9BAA7E9 /* CollectionViewSupplementaryElementRepresentable.swift in Sources */, + 1D5412B8BE164CC40AB37056472738A0 /* column-sort-ascending.png in Sources */, + 3BFE5A7673FE26C58192AE4A4804FB14 /* column-sort-descending.png in Sources */, + A420CBA695BC6A5D41FDDB3556683361 /* column-sort-unspecified.png in Sources */, + 54186B6BB64AA1385130D4CFDF8C1C32 /* DataCell.swift in Sources */, + 2A02F59F62B6257E91B36ABE5DE187E5 /* DataCell.xib in Sources */, + 1682199B9F2387EAB9F0AE264D73BF64 /* DataCellLayoutAttributes.swift in Sources */, + 5ADFDE8DC6E446CEB2F64949A4C64807 /* DataCellRowRepresentable.swift in Sources */, + 4F625F11B00F2A82C79A58683EAE5ED6 /* DataCellViewModel.swift in Sources */, + 0E4DA195C1DD249BC36F46704E6479E5 /* DataHeaderFooter.swift in Sources */, + 879F2DA5C13B4A0B6D519FF3BEC59C48 /* DataHeaderFooter.xib in Sources */, + 9FDCB4FCBE392492BD993DB008E0E331 /* DataHeaderFooterViewModel.swift in Sources */, + 0EDC34D3842A179C17600AF096B5FD74 /* DataStore.swift in Sources */, + A038ED326D306EF638F005DC25DDC868 /* DataStructureModel.swift in Sources */, + 8B9C0C7AC4570DD2E90E213607105E40 /* DataTableConfiguration.swift in Sources */, + C4F12AAD947E94A55DAE928D29577396 /* DataTableSearchTextField.swift in Sources */, + 27B9153C7A19C109271A4606EFE3E633 /* DataTableSortable.swift in Sources */, + CACC1A90A6AE7ED12653C4E1E6335A2F /* DataTableSortType.swift in Sources */, + 0AC82994E79C72757A7C838A957E514A /* DataTableValueType.swift in Sources */, + AA38751546A71EEA92F93C1D73090288 /* MenuLengthHeader.swift in Sources */, + FA72CBA68B50E5EBDCD25648C81BA9AA /* MenuLengthHeader.xib in Sources */, + 604D321EF4346D8126333D5309EABDCE /* MenuLengthHeaderViewModel.swift in Sources */, + 260D49F616F0784BD9D51B7EB6CDC051 /* PaginationHeader.swift in Sources */, + 24F7481937E91176DD274096E22F65B0 /* PaginationHeader.xib in Sources */, + ADFAD95B15D0B645F6F6FDEE5A3F87A4 /* PaginationHeaderViewModel.swift in Sources */, + D3358DC10F15C090C59F1B46BCC5AFE4 /* SwiftDataTable+Extensions.swift in Sources */, + 90EF5F0AEE0C81BA83CB8ADC4AAC9183 /* SwiftDataTable.swift in Sources */, + 1FB1428BB6E1A60FD7E3A379816CFF40 /* SwiftDataTableFlowLayout.swift in Sources */, + E5B9CC9B9DB447A50C0720093EC0D21E /* SwiftDataTables-dummy.m in Sources */, + 6A05AC585F344B122E7D07F157D73C90 /* VirtualPositionTrackable.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -626,7 +621,6 @@ isa = XCBuildConfiguration; baseConfigurationReference = 77FCE7AAEC3AB0B69D0D0F1E47526A55 /* Pods-SwiftDataTables_Example.debug.xcconfig */; buildSettings = { - CLANG_ENABLE_MODULES = YES; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; @@ -653,7 +647,6 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -771,7 +764,6 @@ isa = XCBuildConfiguration; baseConfigurationReference = 80EFFBC331D7B75C7689F478B728663E /* Pods-SwiftDataTables_Example.release.xcconfig */; buildSettings = { - CLANG_ENABLE_MODULES = YES; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; @@ -797,7 +789,6 @@ PRODUCT_NAME = Pods_SwiftDataTables_Example; SDKROOT = iphoneos; SKIP_INSTALL = YES; - SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; diff --git a/Example/Pods/Target Support Files/SwiftDataTables/Info.plist b/Example/Pods/Target Support Files/SwiftDataTables/Info.plist index f92230d..1caf1ff 100644 --- a/Example/Pods/Target Support Files/SwiftDataTables/Info.plist +++ b/Example/Pods/Target Support Files/SwiftDataTables/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.3.0 + 0.3.1 CFBundleSignature ???? CFBundleVersion diff --git a/SwiftDataTables/Classes/DataTableSearchTextField.swift b/SwiftDataTables/Classes/DataTableSearchTextField.swift index 1a5e90e..27b5ebd 100644 --- a/SwiftDataTables/Classes/DataTableSearchTextField.swift +++ b/SwiftDataTables/Classes/DataTableSearchTextField.swift @@ -9,6 +9,39 @@ import UIKit class DataTableSearchTextField: UITextField { - - + + //MARK: - Properties + + //MARK: - Lifecyc le + override func awakeFromNib() { + super.awakeFromNib() + self.setup() + } + + public func setup(){ + self.borderStyle = .none + self.backgroundColor = UIColor.white + } + + override func layoutSubviews() { + super.layoutSubviews() + self.layer.cornerRadius = (self.bounds.height / 2)-1 + } + + let inset: CGFloat = 10 + + // placeholder position + override func textRect(forBounds bounds: CGRect) -> CGRect { + return bounds.insetBy(dx: inset , dy: inset) + } + + // text position + override func editingRect(forBounds bounds: CGRect) -> CGRect { + return bounds.insetBy(dx: inset , dy: inset) + } + + override func placeholderRect(forBounds bounds: CGRect) -> CGRect { + return bounds.insetBy(dx: inset, dy: inset) + } + } diff --git a/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeader.xib b/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeader.xib index e6ace47..9da9944 100644 --- a/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeader.xib +++ b/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeader.xib @@ -15,18 +15,19 @@ - + + + + - - - - + + + + diff --git a/SwiftDataTables/Classes/SwiftDataTable.swift b/SwiftDataTables/Classes/SwiftDataTable.swift index 0b809d8..fa731e1 100644 --- a/SwiftDataTables/Classes/SwiftDataTable.swift +++ b/SwiftDataTables/Classes/SwiftDataTable.swift @@ -22,7 +22,7 @@ public class SwiftDataTable: UIView { case footerHeader = "SwiftDataTableFooterHeader" /// Single header positioned at the bottom below the footer section. - case searchHeader = "SwiftDataTableMenuLengthHeader" + case searchHeader = "SwiftDataTableSearchHeader" init(kind: String){ guard let elementKind = SupplementaryViewType(rawValue: kind) else { @@ -284,7 +284,7 @@ extension SwiftDataTable: UICollectionViewDataSource { public func collectionView(_ collectionView: UICollectionView, willDisplaySupplementaryView view: UICollectionReusableView, forElementKind elementKind: String, at indexPath: IndexPath) { let kind = SupplementaryViewType(kind: elementKind) switch kind { - case .paginationHeader, .searchHeader: + case .paginationHeader: view.backgroundColor = UIColor.darkGray default: view.backgroundColor = UIColor.white @@ -462,10 +462,6 @@ extension SwiftDataTable { return self.dataStructure.footerTitles.count } - func showsSearchBar() -> Bool { - return true - } - func shouldContentWidthScaleToFillFrame() -> Bool{ return true } @@ -479,7 +475,7 @@ extension SwiftDataTable { } func shouldShowSearchSection() -> Bool { - return false + return true } func shouldShowPaginationSection() -> Bool { @@ -541,11 +537,11 @@ extension SwiftDataTable { return 14 } - func heightForMenuLengthView() -> CGFloat { + func heightForSearchView() -> CGFloat { guard self.shouldShowSearchSection() else { return 0 } - return 35 + return 44 } func heightForPaginationView() -> CGFloat { diff --git a/SwiftDataTables/Classes/SwiftDataTableFlowLayout.swift b/SwiftDataTables/Classes/SwiftDataTableFlowLayout.swift index 92a2d49..ea4ebdc 100644 --- a/SwiftDataTables/Classes/SwiftDataTableFlowLayout.swift +++ b/SwiftDataTables/Classes/SwiftDataTableFlowLayout.swift @@ -52,7 +52,7 @@ class SwiftDataTableFlowLayout: UICollectionViewFlowLayout { } //Reduces the computation by calculating the height offset against one column - let defaultUpperHeight = self.dataTable.heightForMenuLengthView() + self.dataTable.heightForSectionHeader() + let defaultUpperHeight = self.dataTable.heightForSearchView() + self.dataTable.heightForSectionHeader() for row in Array(0.. UICollectionViewLayoutAttributes? { let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath) - let initialRowYPosition = self.dataTable.heightForMenuLengthView() + self.dataTable.heightForSectionHeader() + let initialRowYPosition = self.dataTable.heightForSearchView() + self.dataTable.heightForSectionHeader() let x: CGFloat = Array(0.. Date: Wed, 15 Mar 2017 12:00:34 +0000 Subject: [PATCH 04/21] Fixes bug where pagination and search height were mixed up --- Example/Pods/Pods.xcodeproj/project.pbxproj | 2 +- Example/SwiftDataTables/ViewController.swift | 6 +++--- SwiftDataTables/Classes/DataTableSearchTextField.swift | 6 ++++-- SwiftDataTables/Classes/SwiftDataTable.swift | 9 ++++++++- SwiftDataTables/Classes/SwiftDataTableFlowLayout.swift | 9 ++++++--- 5 files changed, 22 insertions(+), 10 deletions(-) diff --git a/Example/Pods/Pods.xcodeproj/project.pbxproj b/Example/Pods/Pods.xcodeproj/project.pbxproj index e87a4b7..f1946fe 100644 --- a/Example/Pods/Pods.xcodeproj/project.pbxproj +++ b/Example/Pods/Pods.xcodeproj/project.pbxproj @@ -270,6 +270,7 @@ 90FCC83B0EA68CB1DD52EBBA8CCA3531 /* Classes */ = { isa = PBXGroup; children = ( + 7AB3AACE6A2F1AFB21B65E918C6BD945 /* SwiftDataTable.swift */, 34D9B4AA17DB4832284C840A91D56FB0 /* DataTableSearchTextField.swift */, 5DD4E394D6FE142F7550AFFFC101A045 /* SwiftDataTableFlowLayout.swift */, 0E4C9491808FD1FFE914DCAFAD7D2386 /* DataStore.swift */, @@ -278,7 +279,6 @@ 9F2E83AB3AB39BF705EE3F1638D6B29F /* DataTableSortable.swift */, D90D3D7ADBC49A31D8FEB1F60C052DE9 /* DataTableSortType.swift */, C4EE833874126E5AF2AA48DB3395A88D /* DataTableValueType.swift */, - 7AB3AACE6A2F1AFB21B65E918C6BD945 /* SwiftDataTable.swift */, 5FBD99A5DED4570C24F2FF9C7839B0F5 /* DataCell */, ADFF8D727187B584BF991FCDDAFC19E9 /* Extensions */, CA8C5D9264EAB22AAB22F465425BC725 /* HeaderFooter */, diff --git a/Example/SwiftDataTables/ViewController.swift b/Example/SwiftDataTables/ViewController.swift index db7f22c..1fb1a7d 100644 --- a/Example/SwiftDataTables/ViewController.swift +++ b/Example/SwiftDataTables/ViewController.swift @@ -25,8 +25,8 @@ class ViewController: UIViewController { super.viewDidLoad() - self.navigationController?.navigationBar.isTranslucent = false - +// self.navigationController?.navigationBar.isTranslucent = false + self.navigationController?.navigationBar.isHidden = true self.view.backgroundColor = UIColor.white var options = DataTableConfiguration() @@ -43,7 +43,7 @@ class ViewController: UIViewController { //25/255, green: 33/255, blue: 39/255, alpha: 1) self.dataTable.autoresizingMask = [.flexibleWidth, .flexibleHeight] - self.dataTable.frame = self.view.bounds + self.dataTable.frame = self.view.frame self.view.addSubview(self.dataTable); } } diff --git a/SwiftDataTables/Classes/DataTableSearchTextField.swift b/SwiftDataTables/Classes/DataTableSearchTextField.swift index 27b5ebd..89e6494 100644 --- a/SwiftDataTables/Classes/DataTableSearchTextField.swift +++ b/SwiftDataTables/Classes/DataTableSearchTextField.swift @@ -8,11 +8,12 @@ import UIKit + class DataTableSearchTextField: UITextField { //MARK: - Properties - - //MARK: - Lifecyc le + + //MARK: - Lifecycle override func awakeFromNib() { super.awakeFromNib() self.setup() @@ -21,6 +22,7 @@ class DataTableSearchTextField: UITextField { public func setup(){ self.borderStyle = .none self.backgroundColor = UIColor.white + self.clearButtonMode = .always } override func layoutSubviews() { diff --git a/SwiftDataTables/Classes/SwiftDataTable.swift b/SwiftDataTables/Classes/SwiftDataTable.swift index fa731e1..c81b5cc 100644 --- a/SwiftDataTables/Classes/SwiftDataTable.swift +++ b/SwiftDataTables/Classes/SwiftDataTable.swift @@ -76,6 +76,8 @@ public class SwiftDataTable: UIView { fileprivate(set) var headerViewModels = [DataHeaderFooterViewModel]() fileprivate(set) var footerViewModels = [DataHeaderFooterViewModel]() fileprivate var rowViewModels = [[DataCellViewModel]]() + fileprivate var searchRowViewModels: [[DataCellViewModel]]? = nil + fileprivate var paginationViewModel: PaginationHeaderViewModel! fileprivate var menuLengthViewModel: MenuLengthHeaderViewModel! fileprivate var columnWidths = [CGFloat]() @@ -447,7 +449,7 @@ extension SwiftDataTable { //This is actually mapped to sections func numberOfRows() -> Int { - return self.rowViewModels.count + return self.searchRowViewModels?.count ?? self.rowViewModels.count } func numberOfColumns() -> Int { @@ -559,3 +561,8 @@ extension SwiftDataTable { return false } } + + +extension SwiftDataTable { + +} diff --git a/SwiftDataTables/Classes/SwiftDataTableFlowLayout.swift b/SwiftDataTables/Classes/SwiftDataTableFlowLayout.swift index ea4ebdc..251cc4d 100644 --- a/SwiftDataTables/Classes/SwiftDataTableFlowLayout.swift +++ b/SwiftDataTables/Classes/SwiftDataTableFlowLayout.swift @@ -53,8 +53,11 @@ class SwiftDataTableFlowLayout: UICollectionViewFlowLayout { //Reduces the computation by calculating the height offset against one column let defaultUpperHeight = self.dataTable.heightForSearchView() + self.dataTable.heightForSectionHeader() + print("Default upper height: \(defaultUpperHeight)") + for row in Array(0.. Date: Wed, 15 Mar 2017 14:07:38 +0000 Subject: [PATCH 05/21] Fixes status bar bug in demo project. Implements floating search section --- Example/SwiftDataTables/ViewController.swift | 7 ++++--- SwiftDataTables/Classes/SwiftDataTable.swift | 7 +++++++ .../Classes/SwiftDataTableFlowLayout.swift | 19 +++++++++++-------- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/Example/SwiftDataTables/ViewController.swift b/Example/SwiftDataTables/ViewController.swift index 1fb1a7d..f6d7181 100644 --- a/Example/SwiftDataTables/ViewController.swift +++ b/Example/SwiftDataTables/ViewController.swift @@ -25,8 +25,8 @@ class ViewController: UIViewController { super.viewDidLoad() -// self.navigationController?.navigationBar.isTranslucent = false - self.navigationController?.navigationBar.isHidden = true + self.navigationController?.navigationBar.isTranslucent = false +// self.navigationController?.navigationBar.isHidden = true self.view.backgroundColor = UIColor.white var options = DataTableConfiguration() @@ -38,7 +38,8 @@ class ViewController: UIViewController { headerTitles: self.columnHeaders(), options: options ) - + self.automaticallyAdjustsScrollViewInsets = false + self.dataTable.backgroundColor = UIColor.init(red: 235/255, green: 235/255, blue: 235/255, alpha: 1) //25/255, green: 33/255, blue: 39/255, alpha: 1) diff --git a/SwiftDataTables/Classes/SwiftDataTable.swift b/SwiftDataTables/Classes/SwiftDataTable.swift index c81b5cc..144c890 100644 --- a/SwiftDataTables/Classes/SwiftDataTable.swift +++ b/SwiftDataTables/Classes/SwiftDataTable.swift @@ -53,6 +53,7 @@ public class SwiftDataTable: UIView { collectionView.allowsMultipleSelection = true collectionView.dataSource = self collectionView.delegate = self + self.addSubview(collectionView) self.registerCell(collectionView: collectionView) return collectionView @@ -476,6 +477,10 @@ extension SwiftDataTable { return true } + func shouldSearchHeaderFloat() -> Bool { + return false + } + func shouldShowSearchSection() -> Bool { return true } @@ -560,6 +565,8 @@ extension SwiftDataTable { func showHorizontalScrollBars() -> Bool { return false } + + } diff --git a/SwiftDataTables/Classes/SwiftDataTableFlowLayout.swift b/SwiftDataTables/Classes/SwiftDataTableFlowLayout.swift index 251cc4d..37d24e7 100644 --- a/SwiftDataTables/Classes/SwiftDataTableFlowLayout.swift +++ b/SwiftDataTables/Classes/SwiftDataTableFlowLayout.swift @@ -89,7 +89,6 @@ class SwiftDataTableFlowLayout: UICollectionViewFlowLayout { ) self.collectionView?.showsVerticalScrollIndicator = self.dataTable.showVerticalScrollBars() - self.collectionView?.showsHorizontalScrollIndicator = self.dataTable.showHorizontalScrollBars() } @@ -173,15 +172,14 @@ extension SwiftDataTableFlowLayout { override func layoutAttributesForSupplementaryView(ofKind elementKind: String, at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? { let kind = SwiftDataTable.SupplementaryViewType(kind: elementKind) switch kind { - case .searchHeader: return self.layoutAttributesForMenuLengthView(at: indexPath) + case .searchHeader: return self.layoutAttributesForHeaderView(at: indexPath) case .columnHeader: return self.layoutAttributesForColumnHeaderView(at: indexPath) case .footerHeader: return self.layoutAttributesForColumnFooterView(at: indexPath) case .paginationHeader: return self.layoutAttributesForPaginationView(at: indexPath) } } - - func layoutAttributesForMenuLengthView(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? { + func layoutAttributesForHeaderView(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? { let attribute = UICollectionViewLayoutAttributes(forSupplementaryViewOfKind: SwiftDataTable.SupplementaryViewType.searchHeader.rawValue, with: indexPath) let x: CGFloat = self.dataTable.collectionView.contentOffset.x let y: CGFloat = 0 @@ -196,12 +194,11 @@ extension SwiftDataTableFlowLayout { ) attribute.zIndex = 5 - if self.dataTable.shouldSectionHeadersFloat(){ + if self.dataTable.shouldSearchHeaderFloat(){ let yOffsetTopView: CGFloat = self.dataTable.collectionView.contentOffset.y attribute.frame.origin.y = yOffsetTopView attribute.zIndex += 1 } - return attribute } @@ -219,10 +216,15 @@ extension SwiftDataTableFlowLayout { width: width, height: height ) + attribute.zIndex = 2 + //This should call the delegate method whether or not the headers should float. - if self.dataTable.shouldSectionHeadersFloat(){ - let yScrollOffsetPosition = self.dataTable.heightForSearchView() + self.collectionView!.contentOffset.y + if self.dataTable.shouldSectionHeadersFloat() { + var yScrollOffsetPosition = self.dataTable.heightForSearchView() + self.collectionView!.contentOffset.y + if false == self.dataTable.shouldSearchHeaderFloat(){ + yScrollOffsetPosition = max(self.dataTable.heightForSearchView(), self.collectionView!.contentOffset.y) + } attribute.frame.origin.y = yScrollOffsetPosition//max(yScrollOffsetPosition, attribute.frame.origin.y) attribute.zIndex += 1 } @@ -244,6 +246,7 @@ extension SwiftDataTableFlowLayout { width: width, height: height ) + attribute.zIndex = 2 //This should call the delegate method whether or not the headers should float. if self.dataTable.shouldSectionFootersFloat(){ From 6ace87d5a623237776d3d5f32535adb0fa77c9b6 Mon Sep 17 00:00:00 2001 From: Pavan Kataria Date: Wed, 15 Mar 2017 15:06:05 +0000 Subject: [PATCH 06/21] Adds target observer to textfield and creates iboutlet to textfield --- .../Classes/MenuLengthHeader/MenuLengthHeader.swift | 9 ++++++++- .../Classes/MenuLengthHeader/MenuLengthHeader.xib | 3 +++ .../MenuLengthHeader/MenuLengthHeaderViewModel.swift | 6 ++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeader.swift b/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeader.swift index e505103..aa3f8a5 100644 --- a/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeader.swift +++ b/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeader.swift @@ -9,12 +9,19 @@ import UIKit class MenuLengthHeader: UICollectionReusableView { - + + //MARK: - Properties + @IBOutlet var searchTextField: DataTableSearchTextField! + + //MARK: - Lifecycle override func awakeFromNib() { super.awakeFromNib() // Initialization code } + func setup(_ viewModel: MenuLengthHeaderViewModel){ +// self.searchTextField.addTarget(viewModel, action: #selector(textFieldDidChange(textField:)), for: .editingChanged) + self.searchTextField.addTarget(viewModel, action: #selector(MenuLengthHeaderViewModel.textFieldDidChange), for: .editingChanged) } } diff --git a/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeader.xib b/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeader.xib index 9da9944..d751ece 100644 --- a/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeader.xib +++ b/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeader.xib @@ -29,6 +29,9 @@ + + + diff --git a/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeaderViewModel.swift b/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeaderViewModel.swift index aff6432..ced703d 100644 --- a/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeaderViewModel.swift +++ b/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeaderViewModel.swift @@ -39,3 +39,9 @@ extension MenuLengthHeaderViewModel: CollectionViewSupplementaryElementRepresent return headerView } } + +extension MenuLengthHeaderViewModel { + @objc func textFieldDidChange(textField: UITextField){ + print("textChanged: \(textField.text)") + } +} From 511d808da2bf72448f93e4dfef821f1a75e408e5 Mon Sep 17 00:00:00 2001 From: Pavan Kataria Date: Wed, 15 Mar 2017 15:11:38 +0000 Subject: [PATCH 07/21] Edits read me to add download counter --- README.md | 1 + .../Classes/MenuLengthHeader/MenuLengthHeader.swift | 5 +---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 0fbace2..352b06b 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ [![GitHub issues](https://img.shields.io/github/issues/pavankataria/SwiftDataTables.svg)](https://github.com/pavankataria/SwiftDataTables/issues) [![Version](https://img.shields.io/cocoapods/v/SwiftDataTables.svg?style=flat)](http://cocoapods.org/pods/SwiftDataTables) [![License](https://img.shields.io/cocoapods/l/SwiftDataTables.svg?style=flat)](http://cocoapods.org/pods/SwiftDataTables) +[![CocoaPods](https://img.shields.io/cocoapods/dt/SwiftDataTables.svg)]() `SwiftDataTables` allows you to display grid-like data sets in a nicely formatted table for iOS. The main goal for the end-user are to be able to obtain useful information from the table as quickly as possible with the following features: ordering, searching, and paging; where as for the developer is to allow for easy implementation with extensible options. diff --git a/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeader.swift b/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeader.swift index aa3f8a5..6048d02 100644 --- a/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeader.swift +++ b/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeader.swift @@ -16,12 +16,9 @@ class MenuLengthHeader: UICollectionReusableView { //MARK: - Lifecycle override func awakeFromNib() { super.awakeFromNib() - // Initialization code } func setup(_ viewModel: MenuLengthHeaderViewModel){ -// self.searchTextField.addTarget(viewModel, action: #selector(textFieldDidChange(textField:)), for: .editingChanged) - - self.searchTextField.addTarget(viewModel, action: #selector(MenuLengthHeaderViewModel.textFieldDidChange), for: .editingChanged) + self.searchTextField.addTarget(viewModel, action: #selector(MenuLengthHeaderViewModel.textFieldDidChange), for: .editingChanged) } } From efae07067eec49fca2615afb278c626ba5e2329a Mon Sep 17 00:00:00 2001 From: Pavan Kataria Date: Wed, 15 Mar 2017 15:27:34 +0000 Subject: [PATCH 08/21] Makes changes to readme and adds closure for search text change --- .README.md.swp | 0 README.md | 8 +++++--- .../MenuLengthHeader/MenuLengthHeaderViewModel.swift | 8 ++++++-- 3 files changed, 11 insertions(+), 5 deletions(-) create mode 100644 .README.md.swp diff --git a/.README.md.swp b/.README.md.swp new file mode 100644 index 0000000..e69de29 diff --git a/README.md b/README.md index 352b06b..7fb3646 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,13 @@ # SwiftDataTables - -[![Platform](https://img.shields.io/cocoapods/p/SwiftDataTables.svg?style=flat)](http://cocoapods.org/pods/SwiftDataTables) + +[![Platform](https://img.shields.io/badge/%20%20Platform%20%20-iOS-brightgreen.svg?style=flat)](http://cocoapods.org/pods/SwiftDataTables) +[![Swift Version](https://img.shields.io/badge/%20%20Swift%20Version%20%20-3.0-brightgreen.svg?style=flat)](http://cocoapods.org/pods/SwiftDataTables) [![GitHub issues](https://img.shields.io/github/issues/pavankataria/SwiftDataTables.svg)](https://github.com/pavankataria/SwiftDataTables/issues) [![Version](https://img.shields.io/cocoapods/v/SwiftDataTables.svg?style=flat)](http://cocoapods.org/pods/SwiftDataTables) [![License](https://img.shields.io/cocoapods/l/SwiftDataTables.svg?style=flat)](http://cocoapods.org/pods/SwiftDataTables) -[![CocoaPods](https://img.shields.io/cocoapods/dt/SwiftDataTables.svg)]() `SwiftDataTables` allows you to display grid-like data sets in a nicely formatted table for iOS. The main goal for the end-user are to be able to obtain useful information from the table as quickly as possible with the following features: ordering, searching, and paging; where as for the developer is to allow for easy implementation with extensible options. diff --git a/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeaderViewModel.swift b/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeaderViewModel.swift index ced703d..b7bdb53 100644 --- a/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeaderViewModel.swift +++ b/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeaderViewModel.swift @@ -10,7 +10,8 @@ import Foundation import UIKit class MenuLengthHeaderViewModel { - + //MARK: - Events + var searchTextFieldDidChangeEvent: ((String) -> Void)? = nil } extension MenuLengthHeaderViewModel: CollectionViewSupplementaryElementRepresentable { @@ -42,6 +43,9 @@ extension MenuLengthHeaderViewModel: CollectionViewSupplementaryElementRepresent extension MenuLengthHeaderViewModel { @objc func textFieldDidChange(textField: UITextField){ - print("textChanged: \(textField.text)") + guard let text = textField.text else { + return + } + self.searchTextFieldDidChangeEvent?(text) } } From e92020fe1a584c8a634becaba2b332907d31b5ed Mon Sep 17 00:00:00 2001 From: Pavan Kataria Date: Wed, 15 Mar 2017 18:01:43 +0000 Subject: [PATCH 09/21] Allows sorting on filtered results, and creates a unified acccess point for row view models --- SwiftDataTables/Classes/SwiftDataTable.swift | 96 +++++++++++++++---- .../Classes/SwiftDataTableFlowLayout.swift | 5 +- 2 files changed, 81 insertions(+), 20 deletions(-) diff --git a/SwiftDataTables/Classes/SwiftDataTable.swift b/SwiftDataTables/Classes/SwiftDataTable.swift index 144c890..fc031b8 100644 --- a/SwiftDataTables/Classes/SwiftDataTable.swift +++ b/SwiftDataTables/Classes/SwiftDataTable.swift @@ -9,7 +9,7 @@ import UIKit public typealias DataTableContent = [[DataTableValueType]] - +public typealias DataTableViewModelContent = [[DataCellViewModel]] public class SwiftDataTable: UIView { public enum SupplementaryViewType: String { /// Single header positioned at the top above the column section @@ -42,6 +42,21 @@ public class SwiftDataTable: UIView { ] //MARK: - Private Properties + var currentRowViewModels: DataTableViewModelContent { + get { + return self.searchRowViewModels ?? self.rowViewModels + } + set { + if self.searchRowViewModels != nil { + self.searchRowViewModels = newValue + } + else { + self.rowViewModels = newValue + } + } + } + + //Lazy var fileprivate(set) open lazy var collectionView: UICollectionView = { guard let layout = self.layout else { @@ -76,8 +91,8 @@ public class SwiftDataTable: UIView { fileprivate(set) var headerViewModels = [DataHeaderFooterViewModel]() fileprivate(set) var footerViewModels = [DataHeaderFooterViewModel]() - fileprivate var rowViewModels = [[DataCellViewModel]]() - fileprivate var searchRowViewModels: [[DataCellViewModel]]? = nil + fileprivate var rowViewModels = DataTableViewModelContent() + fileprivate var searchRowViewModels: DataTableViewModelContent? = nil fileprivate var paginationViewModel: PaginationHeaderViewModel! fileprivate var menuLengthViewModel: MenuLengthHeaderViewModel! @@ -119,7 +134,7 @@ public class SwiftDataTable: UIView { // }() //MARK: - Lifecycle - public init(data: [[DataTableValueType]], + public init(data: DataTableContent, headerTitles: [String], options: DataTableConfiguration = DataTableConfiguration(), frame: CGRect = .zero) @@ -228,13 +243,16 @@ public class SwiftDataTable: UIView { self.layout?.clearLayoutCache() self.collectionView.reloadData() } + public func reloadRowsOnly(){ + + } } public extension SwiftDataTable { func createDataModels(with data: DataStructureModel){ self.dataStructure = data } - func createDataCellViewModels(with dataStructure: DataStructureModel){// -> [[DataCellViewModel]] { + func createDataCellViewModels(with dataStructure: DataStructureModel){// -> DataTableViewModelContent { //1. Create the headers self.headerViewModels = Array(0..<(dataStructure.headerTitles.count)).map { let headerViewModel = DataHeaderFooterViewModel( @@ -255,7 +273,7 @@ public extension SwiftDataTable { } //2. Create the view models - //let viewModels: [[DataCellViewModel]] = + //let viewModels: DataTableViewModelContent = self.rowViewModels = dataStructure.data.map{ currentRowData in return currentRowData.map { return DataCellViewModel(data: $0) @@ -263,6 +281,19 @@ public extension SwiftDataTable { } self.paginationViewModel = PaginationHeaderViewModel() self.menuLengthViewModel = MenuLengthHeaderViewModel() + self.bindViewToModels() + } + + //MARK: - Events + private func bindViewToModels(){ + self.menuLengthViewModel.searchTextFieldDidChangeEvent = { [weak self] text in + self?.searchTextEntryDidChange(text) + } + } + + private func searchTextEntryDidChange(_ text: String){ + //call delegate function + self.executeSearch(text) } } @@ -276,11 +307,11 @@ extension SwiftDataTable: UICollectionViewDataSource { } public func numberOfSections(in collectionView: UICollectionView) -> Int { - return self.rowViewModels.count + return self.numberOfRows() } public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { - let cell = self.rowViewModels[indexPath.section][indexPath.row].dequeueCell(collectionView: collectionView, indexPath: indexPath) + let cell = self.rowModel(at: indexPath).dequeueCell(collectionView: collectionView, indexPath: indexPath) return cell } @@ -294,9 +325,7 @@ extension SwiftDataTable: UICollectionViewDataSource { } } public func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) { - guard let cellViewModel = self.rowViewModels[safe: indexPath.section]?[safe: indexPath.row] else { - return - } + let cellViewModel = self.rowModel(at: indexPath) if cellViewModel.highlighted { cell.backgroundColor = self.highlightedColours[indexPath.section % 2] } @@ -410,16 +439,16 @@ extension SwiftDataTable { switch by { case .ascending: - self.rowViewModels = self.rowViewModels.sorted(by: ascendingOrder) + self.currentRowViewModels = self.currentRowViewModels.sorted(by: ascendingOrder) case .descending: - self.rowViewModels = self.rowViewModels.sorted(by: descendingOrder) + self.currentRowViewModels = self.currentRowViewModels.sorted(by: descendingOrder) default: break } } func highlight(column: Int){ - self.rowViewModels.forEach { + self.currentRowViewModels.forEach { $0.forEach { $0.highlighted = false } $0[column].highlighted = true } @@ -450,7 +479,12 @@ extension SwiftDataTable { //This is actually mapped to sections func numberOfRows() -> Int { - return self.searchRowViewModels?.count ?? self.rowViewModels.count + return self.currentRowViewModels.count + } + + + func rowModel(at indexPath: IndexPath) -> DataCellViewModel { + return self.currentRowViewModels[indexPath.section][indexPath.row] } func numberOfColumns() -> Int { @@ -508,7 +542,6 @@ extension SwiftDataTable { /// - Parameter index: The column index /// - Returns: The automatic width of the column irrespective of the Data Grid frame width func automaticWidthForColumn(index: Int) -> CGFloat { - print(self.frame.width) let columnAverage: CGFloat = CGFloat(dataStructure.averageDataLengthForColumn(index: index)) let sortingArrowVisualElementWidth: CGFloat = 20 // This is ugly let averageDataColumnWidth: CGFloat = columnAverage * self.pixelsPerCharacter() + sortingArrowVisualElementWidth @@ -569,7 +602,34 @@ extension SwiftDataTable { } - +//MARK: - Search extension SwiftDataTable { - + fileprivate func executeSearch(_ needle: String){ + guard false == needle.isEmpty else { + self.searchRowViewModels = nil + //DONT DELETE ORIGINAL CACHE FOR LAYOUTATTRIBUTES + //MAYBE KEEP TWO COPIES.. ONE FOR SEARCH AND ONE FOR DEFAULT +// self.reloadEverything() + return + } + self.searchRowViewModels = [] +// self.reloadEverything() + + Array(0.. Date: Wed, 15 Mar 2017 20:22:16 +0000 Subject: [PATCH 10/21] Filtering working but without resignation of text --- SwiftDataTables/Classes/SwiftDataTable.swift | 22 +++++++++++-------- .../Classes/SwiftDataTableFlowLayout.swift | 2 +- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/SwiftDataTables/Classes/SwiftDataTable.swift b/SwiftDataTables/Classes/SwiftDataTable.swift index fc031b8..d5393a5 100644 --- a/SwiftDataTables/Classes/SwiftDataTable.swift +++ b/SwiftDataTables/Classes/SwiftDataTable.swift @@ -609,27 +609,31 @@ extension SwiftDataTable { self.searchRowViewModels = nil //DONT DELETE ORIGINAL CACHE FOR LAYOUTATTRIBUTES //MAYBE KEEP TWO COPIES.. ONE FOR SEARCH AND ONE FOR DEFAULT -// self.reloadEverything() + self.reloadEverything() return } - self.searchRowViewModels = [] -// self.reloadEverything() - - Array(0.. DataTableViewModelContent { + var filteredSet = DataTableViewModelContent() + Array(0.. Date: Thu, 16 Mar 2017 16:20:00 +0000 Subject: [PATCH 11/21] Changes Structure to presenting rows --- SwiftDataTables/Classes/SwiftDataTable.swift | 118 +++++++++++++++---- 1 file changed, 96 insertions(+), 22 deletions(-) diff --git a/SwiftDataTables/Classes/SwiftDataTable.swift b/SwiftDataTables/Classes/SwiftDataTable.swift index d5393a5..1d60e10 100644 --- a/SwiftDataTables/Classes/SwiftDataTable.swift +++ b/SwiftDataTables/Classes/SwiftDataTable.swift @@ -43,16 +43,19 @@ public class SwiftDataTable: UIView { //MARK: - Private Properties var currentRowViewModels: DataTableViewModelContent { +// return self.searchRowViewModels get { - return self.searchRowViewModels ?? self.rowViewModels +// return self.searchRowViewModels ?? self.rowViewModels + return self.searchRowViewModels } set { - if self.searchRowViewModels != nil { - self.searchRowViewModels = newValue - } - else { - self.rowViewModels = newValue - } + self.searchRowViewModels = newValue +// if self.searchRowViewModels != nil { +// self.searchRowViewModels = newValue +// } +// else { +// self.rowViewModels = newValue +// } } } @@ -91,8 +94,12 @@ public class SwiftDataTable: UIView { fileprivate(set) var headerViewModels = [DataHeaderFooterViewModel]() fileprivate(set) var footerViewModels = [DataHeaderFooterViewModel]() - fileprivate var rowViewModels = DataTableViewModelContent() - fileprivate var searchRowViewModels: DataTableViewModelContent? = nil + fileprivate var rowViewModels = DataTableViewModelContent() { + didSet { + self.searchRowViewModels = rowViewModels + } + } + fileprivate var searchRowViewModels: DataTableViewModelContent! fileprivate var paginationViewModel: PaginationHeaderViewModel! fileprivate var menuLengthViewModel: MenuLengthHeaderViewModel! @@ -604,19 +611,6 @@ extension SwiftDataTable { //MARK: - Search extension SwiftDataTable { - fileprivate func executeSearch(_ needle: String){ - guard false == needle.isEmpty else { - self.searchRowViewModels = nil - //DONT DELETE ORIGINAL CACHE FOR LAYOUTATTRIBUTES - //MAYBE KEEP TWO COPIES.. ONE FOR SEARCH AND ONE FOR DEFAULT - self.reloadEverything() - return - } - self.searchRowViewModels = self.filteredResults(with: needle, on: self.rowViewModels) - print("needle: \(needle), rows found: \(self.searchRowViewModels!.count)") - self.reloadEverything() - } - private func filteredResults(with needle: String, on originalArray: DataTableViewModelContent) -> DataTableViewModelContent { var filteredSet = DataTableViewModelContent() Array(0.. Bool in +// +// return name.lowercased().contains(searchText.lowercased()) +// }) +// } +// +// self.collectionView.performBatchUpdates({ +// +// for (oldIndex, oldName) in oldFilteredNames.enumerated() { +// +// if self.filteredNames.contains(oldName) == false { +// +// let indexPath = IndexPath(item: 0, section: oldIndex+1) +// self.collectionView.deleteSections([oldIndex+1]) +// } +// } +// +// for (index, name) in self.filteredNames.enumerated() { +// +// if oldFilteredNames.contains(name) == false { +// +// let indexPath = IndexPath(item: 0, section: index+1) +// self.collectionView.insertSections([index+1]) +// } +// } +// +// }, completion: nil) +// } } From fd0e934788ba681c9fd90e049f671e6358a4da70 Mon Sep 17 00:00:00 2001 From: Pavan Kataria Date: Thu, 16 Mar 2017 17:04:20 +0000 Subject: [PATCH 12/21] Creates insertion and deletion algorithm --- .../Classes/DataCell/DataCellViewModel.swift | 15 +++++ SwiftDataTables/Classes/SwiftDataTable.swift | 60 +++++++++++-------- 2 files changed, 51 insertions(+), 24 deletions(-) diff --git a/SwiftDataTables/Classes/DataCell/DataCellViewModel.swift b/SwiftDataTables/Classes/DataCell/DataCellViewModel.swift index 94f4068..1915680 100644 --- a/SwiftDataTables/Classes/DataCell/DataCellViewModel.swift +++ b/SwiftDataTables/Classes/DataCell/DataCellViewModel.swift @@ -38,3 +38,18 @@ open class DataCellViewModel: VirtualPositionTrackable, CollectionViewCellRepres return cell } } +extension DataCellViewModel: Equatable { + /// Returns a Boolean value indicating whether two values are equal. + /// + /// Equality is the inverse of inequality. For any values `a` and `b`, + /// `a == b` implies that `a != b` is `false`. + /// + /// - Parameters: + /// - lhs: A value to compare. + /// - rhs: Another value to compare. + public static func ==(lhs: DataCellViewModel, rhs: DataCellViewModel) -> Bool { + return lhs.data == rhs.data + && lhs.highlighted == rhs.highlighted + } + +} diff --git a/SwiftDataTables/Classes/SwiftDataTable.swift b/SwiftDataTables/Classes/SwiftDataTable.swift index 1d60e10..3425a8a 100644 --- a/SwiftDataTables/Classes/SwiftDataTable.swift +++ b/SwiftDataTables/Classes/SwiftDataTable.swift @@ -637,8 +637,7 @@ extension SwiftDataTable { fileprivate func executeSearch(_ needle: String){ - return - let oldFilteredRowViewModels = self.searchRowViewModels + let oldFilteredRowViewModels = self.searchRowViewModels! if needle.isEmpty { //DONT DELETE ORIGINAL CACHE FOR LAYOUTATTRIBUTES @@ -649,31 +648,37 @@ extension SwiftDataTable { self.searchRowViewModels = self.filteredResults(with: needle, on: self.rowViewModels) print("needle: \(needle), rows found: \(self.searchRowViewModels!.count)") } -// self.collectionView.performBatchUpdates({ -// -// for (oldIndex, oldRowViewModel) in oldFilteredRowViewModels?.enumerated() { -// -// if self.filteredNames.contains(oldName) == false { -// -//// let indexPath = IndexPath(item: 0, section: oldIndex) -// self.collectionView.deleteSections([oldIndex]) -// } -// } -// -// for (index, name) in self.filteredNames.enumerated() { -// -// if oldFilteredNames.contains(name) == false { -// -//// let indexPath = IndexPath(item: 0, section: index+1) -// self.collectionView.insertSections([index+1]) -// } -// } -// -// }, completion: nil) + self.collectionView.performBatchUpdates({ + + //finding the differences + + //The current displayed rows - in this case named old - is scanned over.. deleting any entries that are not existing in the newly created filtered list. + + for (oldIndex, oldRowViewModel) in oldFilteredRowViewModels.enumerated() { + + let index = self.searchRowViewModels.index { rowViewModel in + return oldRowViewModel == rowViewModel + } + if index == nil { + self.collectionView.deleteSections([oldIndex]) + } + } + + //Iterates over the new search results and compares them with the current result set displayed - in this case name old - inserting any entries that are not existant in the currently displayed result set + + for (currentIndex, currentRolwViewModel) in self.searchRowViewModels.enumerated() { + let oldIndex = oldFilteredRowViewModels.index { oldRowViewModel in + return currentRolwViewModel == oldRowViewModel + } + if oldIndex == nil { + self.collectionView.insertSections([currentIndex]) + } + } + + }, completion: nil) } // fileprivate func test(){ -// let searchText = "" // let oldFilteredNames = self.filteredNames! // // if searchText.isEmpty { @@ -690,6 +695,11 @@ extension SwiftDataTable { // // self.collectionView.performBatchUpdates({ // +// //finding the differences +// +// //The current result set named old.. is scanned over.. deleting any entries that are not existant +// //in the newly created filtered list. +// // for (oldIndex, oldName) in oldFilteredNames.enumerated() { // // if self.filteredNames.contains(oldName) == false { @@ -699,6 +709,8 @@ extension SwiftDataTable { // } // } // +// +// //Iterates over the new search results and compares them with the current result set displayed - in this case name old - inserting any entries that are not existant in the currently displayed result set // for (index, name) in self.filteredNames.enumerated() { // // if oldFilteredNames.contains(name) == false { From ac718b6bbcda7b3b0de39f849071ae213883f146 Mon Sep 17 00:00:00 2001 From: Pavan Kataria Date: Fri, 17 Mar 2017 09:37:20 +0000 Subject: [PATCH 13/21] Made changes to read me file --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 7fb3646..a6acd63 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,9 @@ This package was inspired by Javascript's DataTables package. To run the example project, clone the repo, and run `pod install` from the Example directory first. ## Requirements ++ iOS 8.0+ ++ Xcode 8 ++ Swift 3 ## Installation From 4a7864f99c2238721296784c96dcf44d3d8a8cf1 Mon Sep 17 00:00:00 2001 From: Pavan Kataria Date: Fri, 17 Mar 2017 11:28:51 +0000 Subject: [PATCH 14/21] Insertions and deletions working .. and keyboard not dismissing as often... still needs fix --- .../SwiftDataTables.xcodeproj/project.pbxproj | 4 +- SwiftDataTables/Classes/SwiftDataTable.swift | 101 +++++++----------- .../Classes/SwiftDataTableFlowLayout.swift | 56 +++++++++- 3 files changed, 96 insertions(+), 65 deletions(-) diff --git a/Example/SwiftDataTables.xcodeproj/project.pbxproj b/Example/SwiftDataTables.xcodeproj/project.pbxproj index 6933edf..0b59307 100644 --- a/Example/SwiftDataTables.xcodeproj/project.pbxproj +++ b/Example/SwiftDataTables.xcodeproj/project.pbxproj @@ -449,7 +449,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -489,7 +489,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; diff --git a/SwiftDataTables/Classes/SwiftDataTable.swift b/SwiftDataTables/Classes/SwiftDataTable.swift index 3425a8a..2aa190c 100644 --- a/SwiftDataTables/Classes/SwiftDataTable.swift +++ b/SwiftDataTables/Classes/SwiftDataTable.swift @@ -71,7 +71,9 @@ public class SwiftDataTable: UIView { collectionView.allowsMultipleSelection = true collectionView.dataSource = self collectionView.delegate = self - + if #available(iOS 10, *) { + collectionView.isPrefetchingEnabled = false + } self.addSubview(collectionView) self.registerCell(collectionView: collectionView) return collectionView @@ -321,7 +323,20 @@ extension SwiftDataTable: UICollectionViewDataSource { let cell = self.rowModel(at: indexPath).dequeueCell(collectionView: collectionView, indexPath: indexPath) return cell } - + public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { + let numberOfItemsInLine: CGFloat = 6 + + let inset = UIEdgeInsets.zero + +// let inset = self.collectionView(collectionView, layout: collectionViewLayout, insetForSectionAt: indexPath.section) + let minimumInteritemSpacing: CGFloat = 0 + let contentwidth: CGFloat = minimumInteritemSpacing * (numberOfItemsInLine - 1) + let itemWidth = (collectionView.frame.width - inset.left - inset.right - contentwidth) / numberOfItemsInLine + let itemHeight: CGFloat = 100 + + return CGSize(width: itemWidth, height: itemHeight) + + } public func collectionView(_ collectionView: UICollectionView, willDisplaySupplementaryView view: UICollectionReusableView, forElementKind elementKind: String, at indexPath: IndexPath) { let kind = SupplementaryViewType(kind: elementKind) switch kind { @@ -632,10 +647,6 @@ extension SwiftDataTable { } - - - - fileprivate func executeSearch(_ needle: String){ let oldFilteredRowViewModels = self.searchRowViewModels! @@ -648,14 +659,24 @@ extension SwiftDataTable { self.searchRowViewModels = self.filteredResults(with: needle, on: self.rowViewModels) print("needle: \(needle), rows found: \(self.searchRowViewModels!.count)") } + self.layout?.clearLayoutCache() + self.differenceSorter(oldRows: oldFilteredRowViewModels, filteredRows: self.searchRowViewModels, + completion: nil) + } + + private func differenceSorter( + oldRows: DataTableViewModelContent, + filteredRows: DataTableViewModelContent, + animations: Bool = false, + completion: ((Bool) -> Void)? = nil){ +// if animations == false { +// UIView.setAnimationsEnabled(false) +// } self.collectionView.performBatchUpdates({ - //finding the differences - //The current displayed rows - in this case named old - is scanned over.. deleting any entries that are not existing in the newly created filtered list. - - for (oldIndex, oldRowViewModel) in oldFilteredRowViewModels.enumerated() { - + //The currently displayed rows - in this case named old rows - is scanned over.. deleting any entries that are not existing in the newly created filtered list. + for (oldIndex, oldRowViewModel) in oldRows.enumerated() { let index = self.searchRowViewModels.index { rowViewModel in return oldRowViewModel == rowViewModel } @@ -665,61 +686,19 @@ extension SwiftDataTable { } //Iterates over the new search results and compares them with the current result set displayed - in this case name old - inserting any entries that are not existant in the currently displayed result set - - for (currentIndex, currentRolwViewModel) in self.searchRowViewModels.enumerated() { - let oldIndex = oldFilteredRowViewModels.index { oldRowViewModel in + for (currentIndex, currentRolwViewModel) in filteredRows.enumerated() { + let oldIndex = oldRows.index { oldRowViewModel in return currentRolwViewModel == oldRowViewModel } if oldIndex == nil { self.collectionView.insertSections([currentIndex]) } } - - }, completion: nil) - } - -// fileprivate func test(){ -// let oldFilteredNames = self.filteredNames! -// -// if searchText.isEmpty { -// -// self.filteredNames = self.names -// } -// else { -// -// self.filteredNames = self.names.filter({ (name) -> Bool in -// -// return name.lowercased().contains(searchText.lowercased()) -// }) -// } -// -// self.collectionView.performBatchUpdates({ -// -// //finding the differences -// -// //The current result set named old.. is scanned over.. deleting any entries that are not existant -// //in the newly created filtered list. -// -// for (oldIndex, oldName) in oldFilteredNames.enumerated() { -// -// if self.filteredNames.contains(oldName) == false { -// -// let indexPath = IndexPath(item: 0, section: oldIndex+1) -// self.collectionView.deleteSections([oldIndex+1]) -// } + }, completion: { finished in +// if animations == false { +// UIView.setAnimationsEnabled(true) // } -// -// -// //Iterates over the new search results and compares them with the current result set displayed - in this case name old - inserting any entries that are not existant in the currently displayed result set -// for (index, name) in self.filteredNames.enumerated() { -// -// if oldFilteredNames.contains(name) == false { -// -// let indexPath = IndexPath(item: 0, section: index+1) -// self.collectionView.insertSections([index+1]) -// } -// } -// -// }, completion: nil) -// } + completion?(finished) + }) + } } diff --git a/SwiftDataTables/Classes/SwiftDataTableFlowLayout.swift b/SwiftDataTables/Classes/SwiftDataTableFlowLayout.swift index 1040237..ecc3d52 100644 --- a/SwiftDataTables/Classes/SwiftDataTableFlowLayout.swift +++ b/SwiftDataTables/Classes/SwiftDataTableFlowLayout.swift @@ -12,9 +12,14 @@ class SwiftDataTableFlowLayout: UICollectionViewFlowLayout { //MARK: - Properties fileprivate(set) open var dataTable: SwiftDataTable! + var insertedIndexPaths = NSMutableArray() + var removedIndexPaths = NSMutableArray() + var insertedSectionIndices = NSMutableArray() + var removedSectionIndices = NSMutableArray() private var cache = [UICollectionViewLayoutAttributes]() - + private var filteredCache = [UICollectionViewLayoutAttributes]() +// private var filteredCache = [UICollectionViewLayoutAttributes]() //MARK: - Lifecycle init(dataTable: SwiftDataTable){ @@ -88,7 +93,10 @@ class SwiftDataTableFlowLayout: UICollectionViewFlowLayout { bottom: self.dataTable.shouldSectionFootersFloat() ? self.dataTable.heightForSectionFooter() + self.dataTable.heightForPaginationView() : 0, right: 0 ) - + self.calculateScrollBarIndicators() + } + + func calculateScrollBarIndicators(){ self.collectionView?.showsVerticalScrollIndicator = self.dataTable.showVerticalScrollBars() self.collectionView?.showsHorizontalScrollIndicator = self.dataTable.showHorizontalScrollBars() } @@ -284,3 +292,47 @@ extension SwiftDataTableFlowLayout { return attribute } } + +//MARK: - Insertions and deletions +//extension SwiftDataTableFlowLayout { +// override func prepare(forCollectionViewUpdates updateItems: [UICollectionViewUpdateItem]) { +// super.prepare(forCollectionViewUpdates: updateItems) +// +// self.insertedIndexPaths = NSMutableArray() +// self.removedIndexPaths = NSMutableArray() +// self.insertedSectionIndices = NSMutableArray() +// self.removedSectionIndices = NSMutableArray() +// +// for (index, updateItem) in updateItems.enumerated() { +// switch updateItem.updateAction { +// case .insert: +// guard let indexPathAfterUpdate = updateItem.indexPathAfterUpdate else { +// break +// } +// if indexPathAfterUpdate.item == NSNotFound { +// self.insertedSectionIndices.add(NSNumber(value: indexPathAfterUpdate.section)) +// } +// else { +// self.insertedIndexPaths.add(indexPathAfterUpdate) +// } +// case .delete: +// guard let indexPathBeforeUpdate = updateItem.indexPathBeforeUpdate else { +// break +// } +// if indexPathBeforeUpdate.item == NSNotFound { +// self.removedSectionIndices.add(NSNumber(value: indexPathBeforeUpdate.section)) +// } +// else { +// self.removedIndexPaths.add(indexPathBeforeUpdate) +// } +// default: +// break +// } +// } +// +// print("insertedIndexPaths: \(self.insertedIndexPaths)") +// print("removedIndexPaths: \(self.removedIndexPaths)") +// print("insertedSectionIndices: \(self.insertedSectionIndices)") +// print("removedSectionIndices: \(self.removedSectionIndices)") +// } +//} From 660f87521c03ecc323c48aff8191c80391155ea9 Mon Sep 17 00:00:00 2001 From: Pavan Kataria Date: Fri, 17 Mar 2017 13:40:30 +0000 Subject: [PATCH 15/21] Changes search bar implementation to use a SearchBar class --- .../MenuLengthHeader/MenuLengthHeader.swift | 10 ++++++++-- .../MenuLengthHeader/MenuLengthHeader.xib | 16 +++++++--------- .../MenuLengthHeaderViewModel.swift | 6 +++++- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeader.swift b/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeader.swift index 6048d02..2f46ec1 100644 --- a/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeader.swift +++ b/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeader.swift @@ -11,7 +11,10 @@ import UIKit class MenuLengthHeader: UICollectionReusableView { //MARK: - Properties - @IBOutlet var searchTextField: DataTableSearchTextField! +// @IBOutlet var searchTextField: DataTableSearchTextField! + @IBOutlet var searchBar: UISearchBar! + + //MARK: - Lifecycle override func awakeFromNib() { @@ -19,6 +22,9 @@ class MenuLengthHeader: UICollectionReusableView { } func setup(_ viewModel: MenuLengthHeaderViewModel){ - self.searchTextField.addTarget(viewModel, action: #selector(MenuLengthHeaderViewModel.textFieldDidChange), for: .editingChanged) +// self.searchTextField.addTarget(viewModel, action: #selector(MenuLengthHeaderViewModel.textFieldDidChange), for: .editingChanged) + self.searchBar.delegate = viewModel + self.searchBar.searchBarStyle = .minimal + self.searchBar.placeholder = "Search"// - \(viewModel.count) names" } } diff --git a/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeader.xib b/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeader.xib index d751ece..57083b1 100644 --- a/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeader.xib +++ b/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeader.xib @@ -15,22 +15,20 @@ - + - - - + - - - - + + + + - + diff --git a/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeaderViewModel.swift b/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeaderViewModel.swift index b7bdb53..4848101 100644 --- a/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeaderViewModel.swift +++ b/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeaderViewModel.swift @@ -9,7 +9,7 @@ import Foundation import UIKit -class MenuLengthHeaderViewModel { +class MenuLengthHeaderViewModel: NSObject { //MARK: - Events var searchTextFieldDidChangeEvent: ((String) -> Void)? = nil } @@ -49,3 +49,7 @@ extension MenuLengthHeaderViewModel { self.searchTextFieldDidChangeEvent?(text) } } + +extension MenuLengthHeaderViewModel: UISearchBarDelegate { + +} From dbe1e4ef75d1f823aee7f0cd05638d36bcab3d23 Mon Sep 17 00:00:00 2001 From: Pavan Kataria Date: Fri, 17 Mar 2017 15:53:48 +0000 Subject: [PATCH 16/21] incorporated search bar on supplementary view, still issues w/ firstresponder --- .../MenuLengthHeader/MenuLengthHeader.swift | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeader.swift b/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeader.swift index 2f46ec1..3808d5b 100644 --- a/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeader.swift +++ b/SwiftDataTables/Classes/MenuLengthHeader/MenuLengthHeader.swift @@ -14,7 +14,8 @@ class MenuLengthHeader: UICollectionReusableView { // @IBOutlet var searchTextField: DataTableSearchTextField! @IBOutlet var searchBar: UISearchBar! - + //MARK: - Events + var searchTextDidChange: ((String) -> Void)? //MARK: - Lifecycle override func awakeFromNib() { @@ -23,8 +24,18 @@ class MenuLengthHeader: UICollectionReusableView { func setup(_ viewModel: MenuLengthHeaderViewModel){ // self.searchTextField.addTarget(viewModel, action: #selector(MenuLengthHeaderViewModel.textFieldDidChange), for: .editingChanged) - self.searchBar.delegate = viewModel + + self.searchTextDidChange = { searchText in + viewModel.searchTextFieldDidChangeEvent?(searchText) + } + self.searchBar.delegate = self self.searchBar.searchBarStyle = .minimal self.searchBar.placeholder = "Search"// - \(viewModel.count) names" } } + +extension MenuLengthHeader: UISearchBarDelegate { + func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { + self.searchTextDidChange?(searchText) + } +} From 71cf63c17b9ee085f5918c1b89a457394b57c019 Mon Sep 17 00:00:00 2001 From: Pavan Kataria Date: Fri, 17 Mar 2017 16:07:32 +0000 Subject: [PATCH 17/21] Makes collectionview frame conform to searchbarheight --- SwiftDataTables/Classes/SwiftDataTable.swift | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/SwiftDataTables/Classes/SwiftDataTable.swift b/SwiftDataTables/Classes/SwiftDataTable.swift index 2aa190c..feae32e 100644 --- a/SwiftDataTables/Classes/SwiftDataTable.swift +++ b/SwiftDataTables/Classes/SwiftDataTable.swift @@ -58,6 +58,7 @@ public class SwiftDataTable: UIView { // } } } + //Lazy var @@ -79,6 +80,13 @@ public class SwiftDataTable: UIView { return collectionView }() + + public override func layoutSubviews() { + super.layoutSubviews() + let searchBarHeight = self.heightForSearchView() + self.collectionView.frame = CGRect.init(x: 0, y: searchBarHeight, width: self.bounds.width, height: self.bounds.height-searchBarHeight) + } + fileprivate(set) var layout: SwiftDataTableFlowLayout? = nil { didSet { if let layout = layout { @@ -538,7 +546,7 @@ extension SwiftDataTable { } func shouldShowSearchSection() -> Bool { - return true + return false } func shouldShowPaginationSection() -> Bool { From a618344f6897afe0df1f07b5f09fa9ebe82f1ce1 Mon Sep 17 00:00:00 2001 From: Pavan Kataria Date: Fri, 17 Mar 2017 16:20:16 +0000 Subject: [PATCH 18/21] ensures headers are fixed whenc ontent offset is in the minus figure --- SwiftDataTables/Classes/SwiftDataTable.swift | 8 ++-- .../Classes/SwiftDataTableFlowLayout.swift | 44 ++++++++++++------- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/SwiftDataTables/Classes/SwiftDataTable.swift b/SwiftDataTables/Classes/SwiftDataTable.swift index feae32e..6de681c 100644 --- a/SwiftDataTables/Classes/SwiftDataTable.swift +++ b/SwiftDataTables/Classes/SwiftDataTable.swift @@ -59,7 +59,9 @@ public class SwiftDataTable: UIView { } } - +// fileprivate(set) open lazy var searchBar: UISearchBar = { +//// let searchBar +// }() //Lazy var fileprivate(set) open lazy var collectionView: UICollectionView = { @@ -67,7 +69,7 @@ public class SwiftDataTable: UIView { fatalError("The layout needs to be set first") } let collectionView = UICollectionView(frame: self.bounds, collectionViewLayout: layout) - collectionView.autoresizingMask = [.flexibleWidth, .flexibleHeight] +// collectionView.autoresizingMask = [.flexibleWidth, .flexibleHeight] collectionView.backgroundColor = UIColor.clear collectionView.allowsMultipleSelection = true collectionView.dataSource = self @@ -546,7 +548,7 @@ extension SwiftDataTable { } func shouldShowSearchSection() -> Bool { - return false + return true } func shouldShowPaginationSection() -> Bool { diff --git a/SwiftDataTables/Classes/SwiftDataTableFlowLayout.swift b/SwiftDataTables/Classes/SwiftDataTableFlowLayout.swift index ecc3d52..deef3fd 100644 --- a/SwiftDataTables/Classes/SwiftDataTableFlowLayout.swift +++ b/SwiftDataTables/Classes/SwiftDataTableFlowLayout.swift @@ -57,7 +57,7 @@ class SwiftDataTableFlowLayout: UICollectionViewFlowLayout { } //Reduces the computation by calculating the height offset against one column - let defaultUpperHeight = self.dataTable.heightForSearchView() + self.dataTable.heightForSectionHeader() + let defaultUpperHeight = /*self.dataTable.heightForSearchView() + */self.dataTable.heightForSectionHeader() var counter = 0 for row in Array(0.. UICollectionViewLayoutAttributes? { let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath) - let initialRowYPosition = self.dataTable.heightForSearchView() + self.dataTable.heightForSectionHeader() + let initialRowYPosition = /*self.dataTable.heightForSearchView() + */self.dataTable.heightForSectionHeader() let x: CGFloat = Array(0.. Date: Fri, 17 Mar 2017 16:46:27 +0000 Subject: [PATCH 19/21] Changes header y position so they no longer scroll down with ycontentoffset --- SwiftDataTables/Classes/SwiftDataTable.swift | 3 +-- SwiftDataTables/Classes/SwiftDataTableFlowLayout.swift | 7 ++----- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/SwiftDataTables/Classes/SwiftDataTable.swift b/SwiftDataTables/Classes/SwiftDataTable.swift index 6de681c..629ccdd 100644 --- a/SwiftDataTables/Classes/SwiftDataTable.swift +++ b/SwiftDataTables/Classes/SwiftDataTable.swift @@ -536,7 +536,7 @@ extension SwiftDataTable { } func shouldSectionHeadersFloat() -> Bool { - return true + return false } func shouldSectionFootersFloat() -> Bool { @@ -567,7 +567,6 @@ extension SwiftDataTable { return 0 } - /// Automatically calcualtes the width the column should be based on the content /// in the rows under the column. /// diff --git a/SwiftDataTables/Classes/SwiftDataTableFlowLayout.swift b/SwiftDataTables/Classes/SwiftDataTableFlowLayout.swift index deef3fd..b3e5cf5 100644 --- a/SwiftDataTables/Classes/SwiftDataTableFlowLayout.swift +++ b/SwiftDataTables/Classes/SwiftDataTableFlowLayout.swift @@ -216,12 +216,12 @@ extension SwiftDataTableFlowLayout { //Because the widths can change between columns we need to get a running total for the x position so far up //until the currnt column header. let x = Array(0.. Date: Fri, 17 Mar 2017 17:31:59 +0000 Subject: [PATCH 20/21] Filtering working --- SwiftDataTables/Classes/SwiftDataTable.swift | 68 +++++++++++++------- 1 file changed, 43 insertions(+), 25 deletions(-) diff --git a/SwiftDataTables/Classes/SwiftDataTable.swift b/SwiftDataTables/Classes/SwiftDataTable.swift index 629ccdd..5e4783b 100644 --- a/SwiftDataTables/Classes/SwiftDataTable.swift +++ b/SwiftDataTables/Classes/SwiftDataTable.swift @@ -59,9 +59,16 @@ public class SwiftDataTable: UIView { } } -// fileprivate(set) open lazy var searchBar: UISearchBar = { -//// let searchBar -// }() + fileprivate(set) open lazy var searchBar: UISearchBar = { + let searchBar = UISearchBar() + searchBar.searchBarStyle = .minimal; + searchBar.placeholder = "Search"; + searchBar.delegate = self +// searchBar.tintColor = UIColor.white + searchBar.barTintColor = UIColor.white + self.addSubview(searchBar) + return searchBar + }() //Lazy var fileprivate(set) open lazy var collectionView: UICollectionView = { @@ -86,6 +93,7 @@ public class SwiftDataTable: UIView { public override func layoutSubviews() { super.layoutSubviews() let searchBarHeight = self.heightForSearchView() + self.searchBar.frame = CGRect.init(x: 0, y: 0, width: self.bounds.width, height: searchBarHeight) self.collectionView.frame = CGRect.init(x: 0, y: searchBarHeight, width: self.bounds.width, height: self.bounds.height-searchBarHeight) } @@ -159,7 +167,6 @@ public class SwiftDataTable: UIView { frame: CGRect = .zero) { super.init(frame: frame) - self.set(data: data, headerTitles: headerTitles, options: options) self.registerObservers() @@ -300,20 +307,20 @@ public extension SwiftDataTable { } self.paginationViewModel = PaginationHeaderViewModel() self.menuLengthViewModel = MenuLengthHeaderViewModel() - self.bindViewToModels() +// self.bindViewToModels() } - //MARK: - Events - private func bindViewToModels(){ - self.menuLengthViewModel.searchTextFieldDidChangeEvent = { [weak self] text in - self?.searchTextEntryDidChange(text) - } - } - - private func searchTextEntryDidChange(_ text: String){ - //call delegate function - self.executeSearch(text) - } +// //MARK: - Events +// private func bindViewToModels(){ +// self.menuLengthViewModel.searchTextFieldDidChangeEvent = { [weak self] text in +// self?.searchTextEntryDidChange(text) +// } +// } +// +// private func searchTextEntryDidChange(_ text: String){ +// //call delegate function +// self.executeSearch(text) +// } } extension SwiftDataTable: UICollectionViewDelegateFlowLayout { @@ -398,6 +405,9 @@ extension SwiftDataTable { //MARK: - UICollection View Delegate extension SwiftDataTable: UIScrollViewDelegate { public func scrollViewDidScroll(_ scrollView: UIScrollView) { + if(self.searchBar.isFirstResponder){ + self.searchBar.resignFirstResponder() + } if self.disableScrollViewLeftBounce() { if (self.collectionView.contentOffset.x <= 0) { self.collectionView.contentOffset.x = 0 @@ -536,7 +546,7 @@ extension SwiftDataTable { } func shouldSectionHeadersFloat() -> Bool { - return false + return true } func shouldSectionFootersFloat() -> Bool { @@ -556,11 +566,11 @@ extension SwiftDataTable { } func heightForSectionFooter() -> CGFloat { - return 50 + return 44 } func heightForSectionHeader() -> CGFloat { - return 50 + return 44 } func widthForRowHeader() -> CGFloat { @@ -678,9 +688,9 @@ extension SwiftDataTable { filteredRows: DataTableViewModelContent, animations: Bool = false, completion: ((Bool) -> Void)? = nil){ -// if animations == false { -// UIView.setAnimationsEnabled(false) -// } + if animations == false { + UIView.setAnimationsEnabled(false) + } self.collectionView.performBatchUpdates({ //finding the differences @@ -704,10 +714,18 @@ extension SwiftDataTable { } } }, completion: { finished in -// if animations == false { -// UIView.setAnimationsEnabled(true) -// } + if animations == false { + UIView.setAnimationsEnabled(true) + } completion?(finished) }) } } + + + +extension SwiftDataTable: UISearchBarDelegate { + public func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { + self.executeSearch(searchText.lowercased()) + } +} From 67fa8495529ac6853c4b2460c693bfad8d52a169 Mon Sep 17 00:00:00 2001 From: Pavan Kataria Date: Fri, 17 Mar 2017 18:16:42 +0000 Subject: [PATCH 21/21] Removes unwanted animations, and adds extension to scroll to top --- .../SwiftDataTable+Extensions.swift | 7 +++++ SwiftDataTables/Classes/SwiftDataTable.swift | 31 +++++++++++-------- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/SwiftDataTables/Classes/Extensions/SwiftDataTable+Extensions.swift b/SwiftDataTables/Classes/Extensions/SwiftDataTable+Extensions.swift index 37266ad..0ba0b96 100644 --- a/SwiftDataTables/Classes/Extensions/SwiftDataTable+Extensions.swift +++ b/SwiftDataTables/Classes/Extensions/SwiftDataTable+Extensions.swift @@ -22,3 +22,10 @@ extension Collection where Indices.Iterator.Element == Index { return indices.contains(index) ? self[index] : nil } } + +extension UIScrollView { + /// Sets content offset to the top. + func resetScrollPositionToTop() { + self.contentOffset = CGPoint(x: -contentInset.left, y: -contentInset.top) + } +} diff --git a/SwiftDataTables/Classes/SwiftDataTable.swift b/SwiftDataTables/Classes/SwiftDataTable.swift index 5e4783b..9a5d5ca 100644 --- a/SwiftDataTables/Classes/SwiftDataTable.swift +++ b/SwiftDataTables/Classes/SwiftDataTable.swift @@ -404,10 +404,13 @@ extension SwiftDataTable { //MARK: - UICollection View Delegate extension SwiftDataTable: UIScrollViewDelegate { - public func scrollViewDidScroll(_ scrollView: UIScrollView) { + public func scrollViewWillBeginDragging(_ scrollView: UIScrollView) { if(self.searchBar.isFirstResponder){ self.searchBar.resignFirstResponder() } + } + public func scrollViewDidScroll(_ scrollView: UIScrollView) { + if self.disableScrollViewLeftBounce() { if (self.collectionView.contentOffset.x <= 0) { self.collectionView.contentOffset.x = 0 @@ -643,10 +646,16 @@ extension SwiftDataTable { } -//MARK: - Search -extension SwiftDataTable { +//MARK: - Search Bar Delegate +extension SwiftDataTable: UISearchBarDelegate { + public func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { + self.executeSearch(searchText) + } + + //TODO: Use Regular expression isntead private func filteredResults(with needle: String, on originalArray: DataTableViewModelContent) -> DataTableViewModelContent { var filteredSet = DataTableViewModelContent() + let needle = needle.lowercased() Array(0..