diff --git a/CHANGELOG.md b/CHANGELOG.md index ff3da8849..75091c04c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,21 +5,25 @@ The changelog for `IGListKit`. Also see the [releases](https://github.com/instag 2.0.0 ----- -This release closes the [2.0.0 milestone](https://github.com/Instagram/IGListKit/milestone/1?closed=1). +This release closes the [2.0.0 milestone](https://github.com/Instagram/IGListKit/milestone/1?closed=1). Thanks to the [19 contributors](https://github.com/Instagram/IGListKit/graphs/contributors) who helped with this release! ### Breaking Changes -- Diff result method `-resultWithUpdatedMovesAsDeleteInserts` removed and replaced with `-resultForBatchUpdates` +- Diff result method `-resultWithUpdatedMovesAsDeleteInserts` removed and replaced with `-resultForBatchUpdates` [(b5aa5e3)](https://github.com/Instagram/IGListKit/commit/b5aa5e39002854c947e777c11ae241f67f24d19c) +- `IGListDiffable` equality method changed from `isEqual:` to `isEqualToDiffableObject:` [(ab890fc)](https://github.com/Instagram/IGListKit/commit/ab890fc6070f170a2db5a383a6296e62dcf75678) ### Enhancements +- Added support for supplementaryViews created from nibs. [Rawlinxx](https://github.com/rawlinxx) [(#90)](https://github.com/Instagram/IGListKit/pull/90) - Added support for cells created from nibs. [Sven Bacia](https://github.com/svenbacia) [(#56)](https://github.com/Instagram/IGListKit/pull/56) - Added an additional initializer for `IGListSingleSectionController` to be able to support single sections created from nibs. An example can be found [here](Example/IGListKitExamples/ViewControllers/SingleSectionViewController.swift). - Fixed `-[IGListAdapter reloadDataWithCompletion:]` not returning early when `collectionView` or `dataSource` is nil and `completion` is nil. [Ben Asher](https://github.com/benasher44) [(#51)](https://github.com/Instagram/IGListKit/pull/51) - Added `-isFirstSection` and `-isLastSection` APIs to `IGListSectionController` - Added support for cells created from storyboard. [Bofei Zhu](https://github.com/zhubofei) [(#92)](https://github.com/Instagram/IGListKit/pull/92) +- Added examples for Today & iMessage extensions. [Sherlouk](https://github.com/Sherlouk) [(#112)](https://github.com/Instagram/IGListKit/pull/112) - Added `tvOS` support. [Jesse Squires](https://github.com/jessesquires) [(#137)](https://github.com/Instagram/IGListKit/pull/137) - Added `tvOS` example pack. [Sherlouk](https://github.com/Sherlouk) [(#141)](https://github.com/Instagram/IGListKit/pull/141) +- Added new `-[IGListAdapter visibleObjects]` API. [Ryan Nystrom](https://github.com/rnystrom) [(386ae07)](https://github.com/Instagram/IGListKit/commit/386ae0786445c06e1eabf074a4181614332f155f) 1.0.0 ----- diff --git a/Example/IGListKitExamples.xcodeproj/project.pbxproj b/Example/IGListKitExamples.xcodeproj/project.pbxproj index 864d99faa..2e98ef799 100644 --- a/Example/IGListKitExamples.xcodeproj/project.pbxproj +++ b/Example/IGListKitExamples.xcodeproj/project.pbxproj @@ -29,6 +29,13 @@ 2961B3AE1D68B0B5001C9451 /* SpinnerCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2961B3A81D68B0B5001C9451 /* SpinnerCell.swift */; }; 2961B3B01D68B28E001C9451 /* SearchCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2961B3AF1D68B28E001C9451 /* SearchCell.swift */; }; 29628F141D91905A0026B15A /* DetailLabelCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29628F131D91905A0026B15A /* DetailLabelCell.swift */; }; + 296DD7531DD2147500206780 /* SelfSizingCellsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 296DD7521DD2147500206780 /* SelfSizingCellsViewController.swift */; }; + 296DD7551DD2150600206780 /* SelfSizingSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 296DD7541DD2150600206780 /* SelfSizingSectionController.swift */; }; + 296DD7571DD2163800206780 /* ManuallySelfSizingCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 296DD7561DD2163800206780 /* ManuallySelfSizingCell.swift */; }; + 296DD7591DD2174200206780 /* NibSelfSizingCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 296DD7581DD2174200206780 /* NibSelfSizingCell.swift */; }; + 296DD75B1DD217C000206780 /* NibSelfSizingCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 296DD75A1DD217C000206780 /* NibSelfSizingCell.xib */; }; + 296DD75D1DD21ADA00206780 /* SelectionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 296DD75C1DD21ADA00206780 /* SelectionModel.swift */; }; + 297546FA1DD25384002A6F89 /* FullWidthSelfSizingCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 297546F91DD25384002A6F89 /* FullWidthSelfSizingCell.swift */; }; 2981BA351DB868A500A987F9 /* ImageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2981BA341DB868A500A987F9 /* ImageCell.swift */; }; 2981BA371DB869FF00A987F9 /* WorkingRangeSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2981BA361DB869FF00A987F9 /* WorkingRangeSectionController.swift */; }; 2981BA391DB874BB00A987F9 /* WorkingRangeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2981BA381DB874BB00A987F9 /* WorkingRangeViewController.swift */; }; @@ -40,15 +47,68 @@ 2991F92C1D7BBE5400B0C58F /* RemoveCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2991F92B1D7BBE5400B0C58F /* RemoveCell.swift */; }; 2991F9301D7BC0E400B0C58F /* EmptyViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2991F92F1D7BC0E400B0C58F /* EmptyViewController.swift */; }; 299B54001D6BD6630074A202 /* SearchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 299B53FF1D6BD6630074A202 /* SearchViewController.swift */; }; + 29C6297B1DCFD857004A5BB1 /* SupplementaryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29C6297A1DCFD857004A5BB1 /* SupplementaryViewController.swift */; }; + 29C6297D1DCFD8E5004A5BB1 /* FeedItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29C6297C1DCFD8E5004A5BB1 /* FeedItem.swift */; }; + 29C6297F1DCFD9E9004A5BB1 /* FeedItemSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29C6297E1DCFD9E9004A5BB1 /* FeedItemSectionController.swift */; }; + 29C629811DCFDAF3004A5BB1 /* UserHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 29C629801DCFDAF3004A5BB1 /* UserHeaderView.xib */; }; + 29C629831DCFDB57004A5BB1 /* UserHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29C629821DCFDB57004A5BB1 /* UserHeaderView.swift */; }; + 29D2E4AD1DD69B6000CD255D /* DisplaySectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29D2E4AC1DD69B6000CD255D /* DisplaySectionController.swift */; }; + 29D2E4AF1DD69C0E00CD255D /* DisplayViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29D2E4AE1DD69C0E00CD255D /* DisplayViewController.swift */; }; + 696C69AF297B6455C862314F /* Pods_IGListKitTodayExample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D64E902433068998DDE711FB /* Pods_IGListKitTodayExample.framework */; }; + 75B39B8327726E4F6AA04B13 /* Pods_IGListKitMessageExample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 60AF908234A48B4187E68DAB /* Pods_IGListKitMessageExample.framework */; }; 814F1E00410200822610BB49 /* Pods_IGListKitExamples.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52A8DC2D07A93D7AA55BC993 /* Pods_IGListKitExamples.framework */; }; - 821BC4B41DB8B25B00172ED0 /* Demo.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 821BC4B31DB8B25B00172ED0 /* Demo.storyboard */; }; 821BC4B61DB8B3DC00172ED0 /* StoryboardViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821BC4B51DB8B3DC00172ED0 /* StoryboardViewController.swift */; }; 821BC4B81DB8B48300172ED0 /* StoryboardCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821BC4B71DB8B48300172ED0 /* StoryboardCell.swift */; }; 821BC4BA1DB8B61200172ED0 /* StoryboardLabelSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821BC4B91DB8B61200172ED0 /* StoryboardLabelSectionController.swift */; }; 82D91B691DBA0EF300E62758 /* SingleSectionStoryboardViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82D91B681DBA0EF300E62758 /* SingleSectionStoryboardViewController.swift */; }; + 986FB7131DBBA60900A65C18 /* Messages.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 986FB7121DBBA60900A65C18 /* Messages.framework */; }; + 986FB7161DBBA60900A65C18 /* MessagesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 986FB7151DBBA60900A65C18 /* MessagesViewController.swift */; }; + 986FB71B1DBBA60900A65C18 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 986FB71A1DBBA60900A65C18 /* Assets.xcassets */; }; + 986FB71F1DBBA60900A65C18 /* IGListKitMessageExample.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 986FB7111DBBA60900A65C18 /* IGListKitMessageExample.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 986FB7281DBBA9B200A65C18 /* LabelSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2942FF881D9F39E00015D24B /* LabelSectionController.swift */; }; + 986FB7291DBBA9C900A65C18 /* LabelCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2961B3A71D68B0B5001C9451 /* LabelCell.swift */; }; + 986FB7311DBBAD8600A65C18 /* NotificationCenter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 986FB7301DBBAD8600A65C18 /* NotificationCenter.framework */; }; + 986FB7341DBBAD8600A65C18 /* TodayViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 986FB7331DBBAD8600A65C18 /* TodayViewController.swift */; }; + 986FB73B1DBBAD8600A65C18 /* IGListKitTodayExample.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 986FB72F1DBBAD8600A65C18 /* IGListKitTodayExample.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 986FB7401DBBAEA600A65C18 /* LabelSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2942FF881D9F39E00015D24B /* LabelSectionController.swift */; }; + 986FB7411DBBAEA900A65C18 /* LabelCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2961B3A71D68B0B5001C9451 /* LabelCell.swift */; }; + 98B4DBF41DC2937A002BA58A /* Demo.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 98B4DBF31DC2937A002BA58A /* Demo.storyboard */; }; /* End PBXBuildFile section */ +/* Begin PBXContainerItemProxy section */ + 986FB71D1DBBA60900A65C18 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 2961B3821D68B031001C9451 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 986FB7101DBBA60900A65C18; + remoteInfo = MessageExtension; + }; + 986FB7391DBBAD8600A65C18 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 2961B3821D68B031001C9451 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 986FB72E1DBBAD8600A65C18; + remoteInfo = IGListKitTodayExample; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 986FB7231DBBA60900A65C18 /* Embed App Extensions */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 13; + files = ( + 986FB73B1DBBAD8600A65C18 /* IGListKitTodayExample.appex in Embed App Extensions */, + 986FB71F1DBBA60900A65C18 /* IGListKitMessageExample.appex in Embed App Extensions */, + ); + name = "Embed App Extensions"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + /* Begin PBXFileReference section */ + 23AAB7BC2B07F9B224D908B2 /* Pods-IGListKitMessageExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-IGListKitMessageExample.release.xcconfig"; path = "Pods/Target Support Files/Pods-IGListKitMessageExample/Pods-IGListKitMessageExample.release.xcconfig"; sourceTree = ""; }; 26271C8D1DAE9D3F0073E116 /* SingleSectionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleSectionViewController.swift; sourceTree = ""; }; 26271C911DAE9EFC0073E116 /* NibCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NibCell.xib; sourceTree = ""; }; 26271C931DAE9F050073E116 /* NibCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NibCell.swift; sourceTree = ""; }; @@ -73,6 +133,13 @@ 2961B3A81D68B0B5001C9451 /* SpinnerCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpinnerCell.swift; sourceTree = ""; }; 2961B3AF1D68B28E001C9451 /* SearchCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SearchCell.swift; sourceTree = ""; }; 29628F131D91905A0026B15A /* DetailLabelCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DetailLabelCell.swift; sourceTree = ""; }; + 296DD7521DD2147500206780 /* SelfSizingCellsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SelfSizingCellsViewController.swift; sourceTree = ""; }; + 296DD7541DD2150600206780 /* SelfSizingSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SelfSizingSectionController.swift; sourceTree = ""; }; + 296DD7561DD2163800206780 /* ManuallySelfSizingCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ManuallySelfSizingCell.swift; sourceTree = ""; }; + 296DD7581DD2174200206780 /* NibSelfSizingCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NibSelfSizingCell.swift; sourceTree = ""; }; + 296DD75A1DD217C000206780 /* NibSelfSizingCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NibSelfSizingCell.xib; sourceTree = ""; }; + 296DD75C1DD21ADA00206780 /* SelectionModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SelectionModel.swift; sourceTree = ""; }; + 297546F91DD25384002A6F89 /* FullWidthSelfSizingCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FullWidthSelfSizingCell.swift; sourceTree = ""; }; 2981BA341DB868A500A987F9 /* ImageCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageCell.swift; sourceTree = ""; }; 2981BA361DB869FF00A987F9 /* WorkingRangeSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WorkingRangeSectionController.swift; sourceTree = ""; }; 2981BA381DB874BB00A987F9 /* WorkingRangeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WorkingRangeViewController.swift; sourceTree = ""; }; @@ -84,13 +151,36 @@ 2991F92B1D7BBE5400B0C58F /* RemoveCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RemoveCell.swift; sourceTree = ""; }; 2991F92F1D7BC0E400B0C58F /* EmptyViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EmptyViewController.swift; sourceTree = ""; }; 299B53FF1D6BD6630074A202 /* SearchViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SearchViewController.swift; sourceTree = ""; }; + 29C6297A1DCFD857004A5BB1 /* SupplementaryViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SupplementaryViewController.swift; sourceTree = ""; }; + 29C6297C1DCFD8E5004A5BB1 /* FeedItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeedItem.swift; sourceTree = ""; }; + 29C6297E1DCFD9E9004A5BB1 /* FeedItemSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeedItemSectionController.swift; sourceTree = ""; }; + 29C629801DCFDAF3004A5BB1 /* UserHeaderView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = UserHeaderView.xib; sourceTree = ""; }; + 29C629821DCFDB57004A5BB1 /* UserHeaderView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserHeaderView.swift; sourceTree = ""; }; + 29D2E4AC1DD69B6000CD255D /* DisplaySectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DisplaySectionController.swift; sourceTree = ""; }; + 29D2E4AE1DD69C0E00CD255D /* DisplayViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DisplayViewController.swift; sourceTree = ""; }; 4125DCD99578FDEF3C373BA0 /* Pods-IGListKitExamples.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-IGListKitExamples.release.xcconfig"; path = "Pods/Target Support Files/Pods-IGListKitExamples/Pods-IGListKitExamples.release.xcconfig"; sourceTree = ""; }; + 45D6CC137030027019AE64D8 /* Pods-IGListKitTodayExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-IGListKitTodayExample.debug.xcconfig"; path = "Pods/Target Support Files/Pods-IGListKitTodayExample/Pods-IGListKitTodayExample.debug.xcconfig"; sourceTree = ""; }; 52A8DC2D07A93D7AA55BC993 /* Pods_IGListKitExamples.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_IGListKitExamples.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 821BC4B31DB8B25B00172ED0 /* Demo.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Demo.storyboard; sourceTree = ""; }; + 5CA315001853FD08906AD911 /* Pods-IGListKitTodayExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-IGListKitTodayExample.release.xcconfig"; path = "Pods/Target Support Files/Pods-IGListKitTodayExample/Pods-IGListKitTodayExample.release.xcconfig"; sourceTree = ""; }; + 60AF908234A48B4187E68DAB /* Pods_IGListKitMessageExample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_IGListKitMessageExample.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 821BC4B51DB8B3DC00172ED0 /* StoryboardViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StoryboardViewController.swift; sourceTree = ""; }; 821BC4B71DB8B48300172ED0 /* StoryboardCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StoryboardCell.swift; sourceTree = ""; }; 821BC4B91DB8B61200172ED0 /* StoryboardLabelSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StoryboardLabelSectionController.swift; sourceTree = ""; }; 82D91B681DBA0EF300E62758 /* SingleSectionStoryboardViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleSectionStoryboardViewController.swift; sourceTree = ""; }; + 97C361B62DE81B6EF3C43D32 /* Pods-MessageExtension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MessageExtension.debug.xcconfig"; path = "Pods/Target Support Files/Pods-MessageExtension/Pods-MessageExtension.debug.xcconfig"; sourceTree = ""; }; + 986FB7111DBBA60900A65C18 /* IGListKitMessageExample.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = IGListKitMessageExample.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + 986FB7121DBBA60900A65C18 /* Messages.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Messages.framework; path = System/Library/Frameworks/Messages.framework; sourceTree = SDKROOT; }; + 986FB7151DBBA60900A65C18 /* MessagesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagesViewController.swift; sourceTree = ""; }; + 986FB71A1DBBA60900A65C18 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 986FB71C1DBBA60900A65C18 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 986FB72F1DBBAD8600A65C18 /* IGListKitTodayExample.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = IGListKitTodayExample.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + 986FB7301DBBAD8600A65C18 /* NotificationCenter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NotificationCenter.framework; path = System/Library/Frameworks/NotificationCenter.framework; sourceTree = SDKROOT; }; + 986FB7331DBBAD8600A65C18 /* TodayViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TodayViewController.swift; sourceTree = ""; }; + 986FB7381DBBAD8600A65C18 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 98B4DBF31DC2937A002BA58A /* Demo.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = Demo.storyboard; path = IGListKitExamples/Storyboard/Demo.storyboard; sourceTree = ""; }; + D64E902433068998DDE711FB /* Pods_IGListKitTodayExample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_IGListKitTodayExample.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D7C1118BDF9C30E23DC1953E /* Pods-IGListKitMessageExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-IGListKitMessageExample.debug.xcconfig"; path = "Pods/Target Support Files/Pods-IGListKitMessageExample/Pods-IGListKitMessageExample.debug.xcconfig"; sourceTree = ""; }; + F2C45EF153119C1563409DCB /* Pods-MessageExtension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MessageExtension.release.xcconfig"; path = "Pods/Target Support Files/Pods-MessageExtension/Pods-MessageExtension.release.xcconfig"; sourceTree = ""; }; FE05AB853448A0705AF80427 /* Pods-IGListKitExamples.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-IGListKitExamples.debug.xcconfig"; path = "Pods/Target Support Files/Pods-IGListKitExamples/Pods-IGListKitExamples.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -103,13 +193,35 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 986FB70E1DBBA60900A65C18 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 986FB7131DBBA60900A65C18 /* Messages.framework in Frameworks */, + 75B39B8327726E4F6AA04B13 /* Pods_IGListKitMessageExample.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 986FB72C1DBBAD8600A65C18 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 986FB7311DBBAD8600A65C18 /* NotificationCenter.framework in Frameworks */, + 696C69AF297B6455C862314F /* Pods_IGListKitTodayExample.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 0853E82EF5C5E4BD4E0760E3 /* Frameworks */ = { isa = PBXGroup; children = ( + 986FB7121DBBA60900A65C18 /* Messages.framework */, 52A8DC2D07A93D7AA55BC993 /* Pods_IGListKitExamples.framework */, + 60AF908234A48B4187E68DAB /* Pods_IGListKitMessageExample.framework */, + 986FB7301DBBAD8600A65C18 /* NotificationCenter.framework */, + D64E902433068998DDE711FB /* Pods_IGListKitTodayExample.framework */, ); name = Frameworks; sourceTree = ""; @@ -118,15 +230,18 @@ isa = PBXGroup; children = ( 2942FF831D9F39E00015D24B /* DemoSectionController.swift */, + 29D2E4AC1DD69B6000CD255D /* DisplaySectionController.swift */, 2942FF841D9F39E00015D24B /* EmbeddedSectionController.swift */, 2942FF851D9F39E00015D24B /* ExpandableSectionController.swift */, + 29C6297E1DCFD9E9004A5BB1 /* FeedItemSectionController.swift */, 2942FF861D9F39E00015D24B /* GridSectionController.swift */, 2942FF871D9F39E00015D24B /* HorizontalSectionController.swift */, 2942FF881D9F39E00015D24B /* LabelSectionController.swift */, 2942FF891D9F39E00015D24B /* RemoveSectionController.swift */, 2942FF8A1D9F39E00015D24B /* SearchSectionController.swift */, - 2942FF8B1D9F39E00015D24B /* UserSectionController.swift */, + 296DD7541DD2150600206780 /* SelfSizingSectionController.swift */, 821BC4B91DB8B61200172ED0 /* StoryboardLabelSectionController.swift */, + 2942FF8B1D9F39E00015D24B /* UserSectionController.swift */, 2981BA361DB869FF00A987F9 /* WorkingRangeSectionController.swift */, ); path = SectionControllers; @@ -136,6 +251,8 @@ isa = PBXGroup; children = ( 2961B38C1D68B031001C9451 /* IGListKitExamples */, + 986FB7141DBBA60900A65C18 /* IGListKitMessageExample */, + 986FB7321DBBAD8600A65C18 /* IGListKitTodayExample */, 2961B38B1D68B031001C9451 /* Products */, 586CEEF7A60B53C23ED20E47 /* Pods */, 0853E82EF5C5E4BD4E0760E3 /* Frameworks */, @@ -146,6 +263,8 @@ isa = PBXGroup; children = ( 2961B38A1D68B031001C9451 /* IGListKitExamples.app */, + 986FB7111DBBA60900A65C18 /* IGListKitMessageExample.appex */, + 986FB72F1DBBAD8600A65C18 /* IGListKitTodayExample.appex */, ); name = Products; sourceTree = ""; @@ -170,16 +289,19 @@ isa = PBXGroup; children = ( 2961B3A41D68B0B5001C9451 /* DemosViewController.swift */, + 29459BFF1DBE48E200F05375 /* DiffTableViewController.swift */, + 29D2E4AE1DD69C0E00CD255D /* DisplayViewController.swift */, 2991F92F1D7BC0E400B0C58F /* EmptyViewController.swift */, 2961B3A51D68B0B5001C9451 /* LoadMoreViewController.swift */, 299068271D75BFEC00A62888 /* MixedDataViewController.swift */, 2991F9231D7BB89F00B0C58F /* NestedAdapterViewController.swift */, 299B53FF1D6BD6630074A202 /* SearchViewController.swift */, + 296DD7521DD2147500206780 /* SelfSizingCellsViewController.swift */, + 82D91B681DBA0EF300E62758 /* SingleSectionStoryboardViewController.swift */, 26271C8D1DAE9D3F0073E116 /* SingleSectionViewController.swift */, 821BC4B51DB8B3DC00172ED0 /* StoryboardViewController.swift */, + 29C6297A1DCFD857004A5BB1 /* SupplementaryViewController.swift */, 2981BA381DB874BB00A987F9 /* WorkingRangeViewController.swift */, - 82D91B681DBA0EF300E62758 /* SingleSectionStoryboardViewController.swift */, - 29459BFF1DBE48E200F05375 /* DiffTableViewController.swift */, ); path = ViewControllers; sourceTree = ""; @@ -190,14 +312,20 @@ 2991F9181D7BADC900B0C58F /* CenterLabelCell.swift */, 29628F131D91905A0026B15A /* DetailLabelCell.swift */, 2991F9271D7BB9EC00B0C58F /* EmbeddedCollectionViewCell.swift */, + 297546F91DD25384002A6F89 /* FullWidthSelfSizingCell.swift */, + 2981BA341DB868A500A987F9 /* ImageCell.swift */, 2961B3A71D68B0B5001C9451 /* LabelCell.swift */, + 296DD7561DD2163800206780 /* ManuallySelfSizingCell.swift */, + 26271C931DAE9F050073E116 /* NibCell.swift */, + 26271C911DAE9EFC0073E116 /* NibCell.xib */, + 296DD7581DD2174200206780 /* NibSelfSizingCell.swift */, + 296DD75A1DD217C000206780 /* NibSelfSizingCell.xib */, 2991F92B1D7BBE5400B0C58F /* RemoveCell.swift */, 2961B3AF1D68B28E001C9451 /* SearchCell.swift */, 2961B3A81D68B0B5001C9451 /* SpinnerCell.swift */, - 26271C931DAE9F050073E116 /* NibCell.swift */, - 26271C911DAE9EFC0073E116 /* NibCell.xib */, 821BC4B71DB8B48300172ED0 /* StoryboardCell.swift */, - 2981BA341DB868A500A987F9 /* ImageCell.swift */, + 29C629821DCFDB57004A5BB1 /* UserHeaderView.swift */, + 29C629801DCFDAF3004A5BB1 /* UserHeaderView.xib */, ); path = Views; sourceTree = ""; @@ -205,6 +333,8 @@ 2991F91C1D7BB30300B0C58F /* Models */ = { isa = PBXGroup; children = ( + 29C6297C1DCFD8E5004A5BB1 /* FeedItem.swift */, + 296DD75C1DD21ADA00206780 /* SelectionModel.swift */, 2991F91D1D7BB30C00B0C58F /* User.swift */, ); path = Models; @@ -215,6 +345,12 @@ children = ( FE05AB853448A0705AF80427 /* Pods-IGListKitExamples.debug.xcconfig */, 4125DCD99578FDEF3C373BA0 /* Pods-IGListKitExamples.release.xcconfig */, + 97C361B62DE81B6EF3C43D32 /* Pods-MessageExtension.debug.xcconfig */, + F2C45EF153119C1563409DCB /* Pods-MessageExtension.release.xcconfig */, + D7C1118BDF9C30E23DC1953E /* Pods-IGListKitMessageExample.debug.xcconfig */, + 23AAB7BC2B07F9B224D908B2 /* Pods-IGListKitMessageExample.release.xcconfig */, + 45D6CC137030027019AE64D8 /* Pods-IGListKitTodayExample.debug.xcconfig */, + 5CA315001853FD08906AD911 /* Pods-IGListKitTodayExample.release.xcconfig */, ); name = Pods; sourceTree = ""; @@ -222,12 +358,47 @@ 822B29F21DB8AA4700010000 /* Storyboard */ = { isa = PBXGroup; children = ( - 821BC4B31DB8B25B00172ED0 /* Demo.storyboard */, + 98B4DBF31DC2937A002BA58A /* Demo.storyboard */, ); name = Storyboard; path = ..; sourceTree = ""; }; + 986FB7141DBBA60900A65C18 /* IGListKitMessageExample */ = { + isa = PBXGroup; + children = ( + 986FB71A1DBBA60900A65C18 /* Assets.xcassets */, + 986FB71C1DBBA60900A65C18 /* Info.plist */, + 986FB72A1DBBAC8500A65C18 /* ViewControllers */, + ); + path = IGListKitMessageExample; + sourceTree = ""; + }; + 986FB72A1DBBAC8500A65C18 /* ViewControllers */ = { + isa = PBXGroup; + children = ( + 986FB7151DBBA60900A65C18 /* MessagesViewController.swift */, + ); + name = ViewControllers; + sourceTree = ""; + }; + 986FB7321DBBAD8600A65C18 /* IGListKitTodayExample */ = { + isa = PBXGroup; + children = ( + 986FB7381DBBAD8600A65C18 /* Info.plist */, + 986FB73F1DBBADE400A65C18 /* ViewControllers */, + ); + path = IGListKitTodayExample; + sourceTree = ""; + }; + 986FB73F1DBBADE400A65C18 /* ViewControllers */ = { + isa = PBXGroup; + children = ( + 986FB7331DBBAD8600A65C18 /* TodayViewController.swift */, + ); + name = ViewControllers; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -241,30 +412,79 @@ 2961B3881D68B031001C9451 /* Resources */, 039A6995573B39194F228EF3 /* [CP] Embed Pods Frameworks */, 206BF58DBD30DB5B770B9684 /* [CP] Copy Pods Resources */, + 986FB7231DBBA60900A65C18 /* Embed App Extensions */, ); buildRules = ( ); dependencies = ( + 986FB71E1DBBA60900A65C18 /* PBXTargetDependency */, + 986FB73A1DBBAD8600A65C18 /* PBXTargetDependency */, ); name = IGListKitExamples; productName = IGListKitExamples; productReference = 2961B38A1D68B031001C9451 /* IGListKitExamples.app */; productType = "com.apple.product-type.application"; }; + 986FB7101DBBA60900A65C18 /* IGListKitMessageExample */ = { + isa = PBXNativeTarget; + buildConfigurationList = 986FB7221DBBA60900A65C18 /* Build configuration list for PBXNativeTarget "IGListKitMessageExample" */; + buildPhases = ( + 986FB7251DBBA85C00A65C18 /* [CP] Check Pods Manifest.lock */, + 986FB70D1DBBA60900A65C18 /* Sources */, + 986FB70E1DBBA60900A65C18 /* Frameworks */, + 986FB70F1DBBA60900A65C18 /* Resources */, + 986FB7271DBBA88D00A65C18 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = IGListKitMessageExample; + productName = MessageExtension; + productReference = 986FB7111DBBA60900A65C18 /* IGListKitMessageExample.appex */; + productType = "com.apple.product-type.app-extension.messages"; + }; + 986FB72E1DBBAD8600A65C18 /* IGListKitTodayExample */ = { + isa = PBXNativeTarget; + buildConfigurationList = 986FB73C1DBBAD8600A65C18 /* Build configuration list for PBXNativeTarget "IGListKitTodayExample" */; + buildPhases = ( + 0869ED4F15D1669CAE5FA85C /* [CP] Check Pods Manifest.lock */, + 986FB72B1DBBAD8600A65C18 /* Sources */, + 986FB72C1DBBAD8600A65C18 /* Frameworks */, + 986FB72D1DBBAD8600A65C18 /* Resources */, + C75B27040F25B059CCF6A145 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = IGListKitTodayExample; + productName = IGListKitTodayExample; + productReference = 986FB72F1DBBAD8600A65C18 /* IGListKitTodayExample.appex */; + productType = "com.apple.product-type.app-extension"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 2961B3821D68B031001C9451 /* Project object */ = { isa = PBXProject; attributes = { - LastSwiftUpdateCheck = 0730; + LastSwiftUpdateCheck = 0810; LastUpgradeCheck = 0800; ORGANIZATIONNAME = Instagram; TargetAttributes = { 2961B3891D68B031001C9451 = { CreatedOnToolsVersion = 7.3.1; LastSwiftMigration = 0800; - ProvisioningStyle = Manual; + ProvisioningStyle = Automatic; + }; + 986FB7101DBBA60900A65C18 = { + CreatedOnToolsVersion = 8.1; + ProvisioningStyle = Automatic; + }; + 986FB72E1DBBAD8600A65C18 = { + CreatedOnToolsVersion = 8.1; + ProvisioningStyle = Automatic; }; }; }; @@ -282,6 +502,8 @@ projectRoot = ""; targets = ( 2961B3891D68B031001C9451 /* IGListKitExamples */, + 986FB7101DBBA60900A65C18 /* IGListKitMessageExample */, + 986FB72E1DBBAD8600A65C18 /* IGListKitTodayExample */, ); }; /* End PBXProject section */ @@ -291,10 +513,27 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 29C629811DCFDAF3004A5BB1 /* UserHeaderView.xib in Resources */, + 296DD75B1DD217C000206780 /* NibSelfSizingCell.xib in Resources */, 2961B3981D68B031001C9451 /* LaunchScreen.storyboard in Resources */, 26271C921DAE9EFC0073E116 /* NibCell.xib in Resources */, 2961B3951D68B031001C9451 /* Assets.xcassets in Resources */, - 821BC4B41DB8B25B00172ED0 /* Demo.storyboard in Resources */, + 98B4DBF41DC2937A002BA58A /* Demo.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 986FB70F1DBBA60900A65C18 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 986FB71B1DBBA60900A65C18 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 986FB72D1DBBAD8600A65C18 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( ); runOnlyForDeploymentPostprocessing = 0; }; @@ -316,6 +555,21 @@ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-IGListKitExamples/Pods-IGListKitExamples-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; + 0869ED4F15D1669CAE5FA85C /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; 206BF58DBD30DB5B770B9684 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -346,6 +600,49 @@ shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; showEnvVarsInLog = 0; }; + 986FB7251DBBA85C00A65C18 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + }; + 986FB7271DBBA88D00A65C18 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-IGListKitMessageExample/Pods-IGListKitMessageExample-resources.sh\"\n"; + }; + C75B27040F25B059CCF6A145 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-IGListKitTodayExample/Pods-IGListKitTodayExample-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -356,18 +653,24 @@ 299068281D75BFEC00A62888 /* MixedDataViewController.swift in Sources */, 299B54001D6BD6630074A202 /* SearchViewController.swift in Sources */, 2961B3AE1D68B0B5001C9451 /* SpinnerCell.swift in Sources */, + 296DD7591DD2174200206780 /* NibSelfSizingCell.swift in Sources */, + 296DD7531DD2147500206780 /* SelfSizingCellsViewController.swift in Sources */, 2961B3B01D68B28E001C9451 /* SearchCell.swift in Sources */, 2942FF8C1D9F39E00015D24B /* DemoSectionController.swift in Sources */, 2981BA351DB868A500A987F9 /* ImageCell.swift in Sources */, 2942FF931D9F39E00015D24B /* SearchSectionController.swift in Sources */, + 297546FA1DD25384002A6F89 /* FullWidthSelfSizingCell.swift in Sources */, 82D91B691DBA0EF300E62758 /* SingleSectionStoryboardViewController.swift in Sources */, + 29D2E4AF1DD69C0E00CD255D /* DisplayViewController.swift in Sources */, 2942FF911D9F39E00015D24B /* LabelSectionController.swift in Sources */, 2981BA391DB874BB00A987F9 /* WorkingRangeViewController.swift in Sources */, + 29C629831DCFDB57004A5BB1 /* UserHeaderView.swift in Sources */, 2961B3AC1D68B0B5001C9451 /* LoadMoreViewController.swift in Sources */, 26271C941DAE9F050073E116 /* NibCell.swift in Sources */, 2991F9191D7BADC900B0C58F /* CenterLabelCell.swift in Sources */, 29628F141D91905A0026B15A /* DetailLabelCell.swift in Sources */, 2991F9301D7BC0E400B0C58F /* EmptyViewController.swift in Sources */, + 29D2E4AD1DD69B6000CD255D /* DisplaySectionController.swift in Sources */, 2991F91E1D7BB30C00B0C58F /* User.swift in Sources */, 2991F9241D7BB89F00B0C58F /* NestedAdapterViewController.swift in Sources */, 2961B38E1D68B031001C9451 /* AppDelegate.swift in Sources */, @@ -375,6 +678,8 @@ 29459C001DBE48E200F05375 /* DiffTableViewController.swift in Sources */, 2991F92C1D7BBE5400B0C58F /* RemoveCell.swift in Sources */, 2942FF8D1D9F39E00015D24B /* EmbeddedSectionController.swift in Sources */, + 29C6297B1DCFD857004A5BB1 /* SupplementaryViewController.swift in Sources */, + 296DD7551DD2150600206780 /* SelfSizingSectionController.swift in Sources */, 2991F9281D7BB9EC00B0C58F /* EmbeddedCollectionViewCell.swift in Sources */, 2942FF8F1D9F39E00015D24B /* GridSectionController.swift in Sources */, 821BC4B81DB8B48300172ED0 /* StoryboardCell.swift in Sources */, @@ -384,14 +689,51 @@ 2942FF901D9F39E00015D24B /* HorizontalSectionController.swift in Sources */, 2981BA371DB869FF00A987F9 /* WorkingRangeSectionController.swift in Sources */, 2961B3AB1D68B0B5001C9451 /* DemosViewController.swift in Sources */, + 296DD75D1DD21ADA00206780 /* SelectionModel.swift in Sources */, + 29C6297D1DCFD8E5004A5BB1 /* FeedItem.swift in Sources */, 821BC4B61DB8B3DC00172ED0 /* StoryboardViewController.swift in Sources */, + 296DD7571DD2163800206780 /* ManuallySelfSizingCell.swift in Sources */, + 29C6297F1DCFD9E9004A5BB1 /* FeedItemSectionController.swift in Sources */, 2942FF8E1D9F39E00015D24B /* ExpandableSectionController.swift in Sources */, 821BC4BA1DB8B61200172ED0 /* StoryboardLabelSectionController.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; + 986FB70D1DBBA60900A65C18 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 986FB7281DBBA9B200A65C18 /* LabelSectionController.swift in Sources */, + 986FB7291DBBA9C900A65C18 /* LabelCell.swift in Sources */, + 986FB7161DBBA60900A65C18 /* MessagesViewController.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 986FB72B1DBBAD8600A65C18 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 986FB7401DBBAEA600A65C18 /* LabelSectionController.swift in Sources */, + 986FB7411DBBAEA900A65C18 /* LabelCell.swift in Sources */, + 986FB7341DBBAD8600A65C18 /* TodayViewController.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ +/* Begin PBXTargetDependency section */ + 986FB71E1DBBA60900A65C18 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 986FB7101DBBA60900A65C18 /* IGListKitMessageExample */; + targetProxy = 986FB71D1DBBA60900A65C18 /* PBXContainerItemProxy */; + }; + 986FB73A1DBBAD8600A65C18 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 986FB72E1DBBAD8600A65C18 /* IGListKitTodayExample */; + targetProxy = 986FB7391DBBAD8600A65C18 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + /* Begin PBXVariantGroup section */ 2961B3961D68B031001C9451 /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; @@ -496,8 +838,10 @@ isa = XCBuildConfiguration; baseConfigurationReference = FE05AB853448A0705AF80427 /* Pods-IGListKitExamples.debug.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = IGListKitExamples/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 8.0; @@ -514,8 +858,10 @@ isa = XCBuildConfiguration; baseConfigurationReference = 4125DCD99578FDEF3C373BA0 /* Pods-IGListKitExamples.release.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = IGListKitExamples/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 8.0; @@ -527,6 +873,82 @@ }; name = Release; }; + 986FB7201DBBA60900A65C18 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D7C1118BDF9C30E23DC1953E /* Pods-IGListKitMessageExample.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = "iMessage App Icon"; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_SUSPICIOUS_MOVES = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = "$(SRCROOT)/IGListKitMessageExample/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.instagram.IGListKitExamples.IGListKitMessageExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 986FB7211DBBA60900A65C18 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 23AAB7BC2B07F9B224D908B2 /* Pods-IGListKitMessageExample.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = "iMessage App Icon"; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_SUSPICIOUS_MOVES = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = "$(SRCROOT)/IGListKitMessageExample/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.instagram.IGListKitExamples.IGListKitMessageExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; + 986FB73D1DBBAD8600A65C18 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 45D6CC137030027019AE64D8 /* Pods-IGListKitTodayExample.debug.xcconfig */; + buildSettings = { + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_SUSPICIOUS_MOVES = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = IGListKitTodayExample/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.instagram.IGListKitExamples.IGListKitTodayExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 986FB73E1DBBAD8600A65C18 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 5CA315001853FD08906AD911 /* Pods-IGListKitTodayExample.release.xcconfig */; + buildSettings = { + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_SUSPICIOUS_MOVES = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = IGListKitTodayExample/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.instagram.IGListKitExamples.IGListKitTodayExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -548,6 +970,24 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 986FB7221DBBA60900A65C18 /* Build configuration list for PBXNativeTarget "IGListKitMessageExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 986FB7201DBBA60900A65C18 /* Debug */, + 986FB7211DBBA60900A65C18 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 986FB73C1DBBAD8600A65C18 /* Build configuration list for PBXNativeTarget "IGListKitTodayExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 986FB73D1DBBAD8600A65C18 /* Debug */, + 986FB73E1DBBAD8600A65C18 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ }; rootObject = 2961B3821D68B031001C9451 /* Project object */; diff --git a/Example/IGListKitExamples.xcodeproj/xcshareddata/xcschemes/IGListKitMessageExample.xcscheme b/Example/IGListKitExamples.xcodeproj/xcshareddata/xcschemes/IGListKitMessageExample.xcscheme new file mode 100644 index 000000000..f91e8a4f7 --- /dev/null +++ b/Example/IGListKitExamples.xcodeproj/xcshareddata/xcschemes/IGListKitMessageExample.xcscheme @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example/IGListKitExamples.xcodeproj/xcshareddata/xcschemes/IGListKitTodayExample.xcscheme b/Example/IGListKitExamples.xcodeproj/xcshareddata/xcschemes/IGListKitTodayExample.xcscheme new file mode 100644 index 000000000..d39d19ce5 --- /dev/null +++ b/Example/IGListKitExamples.xcodeproj/xcshareddata/xcschemes/IGListKitTodayExample.xcscheme @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example/IGListKitExamples/Info.plist b/Example/IGListKitExamples/Info.plist index ae683fbbf..4e48e0ba9 100644 --- a/Example/IGListKitExamples/Info.plist +++ b/Example/IGListKitExamples/Info.plist @@ -36,6 +36,8 @@ UISupportedInterfaceOrientations UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight diff --git a/Example/IGListKitExamples/Models/FeedItem.swift b/Example/IGListKitExamples/Models/FeedItem.swift new file mode 100644 index 000000000..317ddbf5d --- /dev/null +++ b/Example/IGListKitExamples/Models/FeedItem.swift @@ -0,0 +1,41 @@ +/** + Copyright (c) 2016-present, Facebook, Inc. All rights reserved. + + The examples provided by Facebook are for non-commercial testing and evaluation + purposes only. Facebook reserves all rights not expressly granted. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +import IGListKit + +final class FeedItem: IGListDiffable { + + let pk: Int + let user: User + let comments: [String] + + init(pk: Int, user: User, comments: [String]) { + self.pk = pk + self.user = user + self.comments = comments + } + + //MARK: IGListDiffable + + func diffIdentifier() -> NSObjectProtocol { + return pk as NSObjectProtocol + } + + func isEqual(toDiffableObject object: IGListDiffable?) -> Bool { + guard self !== object else { return true } + guard let object = object as? FeedItem else { return false } + return user.isEqual(toDiffableObject: object.user) && comments == object.comments + } + +} diff --git a/Example/IGListKitExamples/Models/SelectionModel.swift b/Example/IGListKitExamples/Models/SelectionModel.swift new file mode 100644 index 000000000..3be2b01f9 --- /dev/null +++ b/Example/IGListKitExamples/Models/SelectionModel.swift @@ -0,0 +1,31 @@ +/** + Copyright (c) 2016-present, Facebook, Inc. All rights reserved. + + The examples provided by Facebook are for non-commercial testing and evaluation + purposes only. Facebook reserves all rights not expressly granted. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +import IGListKit + +enum SelectionModelType: Int { + case none, fullWidth, nib +} + +final class SelectionModel: NSObject { + + let options: [String] + let type: SelectionModelType + + init(options: [String], type: SelectionModelType = .none) { + self.options = options + self.type = type + } + +} diff --git a/Example/IGListKitExamples/Models/User.swift b/Example/IGListKitExamples/Models/User.swift index 39a3082cc..a2cb5ab23 100644 --- a/Example/IGListKitExamples/Models/User.swift +++ b/Example/IGListKitExamples/Models/User.swift @@ -14,7 +14,7 @@ import IGListKit -class User: IGListDiffable { +final class User: IGListDiffable { let pk: Int let name: String @@ -32,14 +32,10 @@ class User: IGListDiffable { return pk as NSObjectProtocol } - func isEqual(_ object: IGListDiffable?) -> Bool { - if self === object { - return true - } - if let object = object as? User { - return name == object.name && handle == object.handle - } - return false + func isEqual(toDiffableObject object: IGListDiffable?) -> Bool { + guard self !== object else { return true } + guard let object = object as? User else { return false } + return name == object.name && handle == object.handle } } diff --git a/Example/IGListKitExamples/SectionControllers/DemoSectionController.swift b/Example/IGListKitExamples/SectionControllers/DemoSectionController.swift index 6b84f019b..d10972f8c 100644 --- a/Example/IGListKitExamples/SectionControllers/DemoSectionController.swift +++ b/Example/IGListKitExamples/SectionControllers/DemoSectionController.swift @@ -33,7 +33,7 @@ class DemoItem: NSObject { } -class DemoSectionController: IGListSectionController, IGListSectionType { +final class DemoSectionController: IGListSectionController, IGListSectionType { var object: DemoItem? diff --git a/Example/IGListKitExamples/SectionControllers/DisplaySectionController.swift b/Example/IGListKitExamples/SectionControllers/DisplaySectionController.swift new file mode 100644 index 000000000..01c242035 --- /dev/null +++ b/Example/IGListKitExamples/SectionControllers/DisplaySectionController.swift @@ -0,0 +1,67 @@ +/** + Copyright (c) 2016-present, Facebook, Inc. All rights reserved. + + The examples provided by Facebook are for non-commercial testing and evaluation + purposes only. Facebook reserves all rights not expressly granted. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +import UIKit +import IGListKit + +class DisplaySectionController: IGListSectionController, IGListSectionType, IGListDisplayDelegate { + + override init() { + super.init() + displayDelegate = self + inset = UIEdgeInsets(top: 0, left: 0, bottom: 30, right: 0) + } + + func numberOfItems() -> Int { + return 4 + } + + func sizeForItem(at index: Int) -> CGSize { + return CGSize(width: collectionContext!.containerSize.width, height: 55) + } + + func cellForItem(at index: Int) -> UICollectionViewCell { + let cell = collectionContext!.dequeueReusableCell(of: LabelCell.self, for: self, at: index) as! LabelCell + let section = collectionContext!.section(for: self) + cell.label.text = "Section \(section), cell \(index)" + return cell + } + + func didUpdate(to object: Any) {} + + func didSelectItem(at index: Int) {} + + // MARK: IGListDisplayDelegate + + func listAdapter(_ listAdapter: IGListAdapter, willDisplay sectionController: IGListSectionController) { + let section = collectionContext!.section(for: self) + print("Will display section \(section)") + } + + func listAdapter(_ listAdapter: IGListAdapter, willDisplay sectionController: IGListSectionController, cell: UICollectionViewCell, at index: Int) { + let section = collectionContext!.section(for: self) + print("Did will display cell \(index) in section \(section)") + } + + func listAdapter(_ listAdapter: IGListAdapter, didEndDisplaying sectionController: IGListSectionController) { + let section = collectionContext!.section(for: self) + print("Did end displaying section \(section)") + } + + func listAdapter(_ listAdapter: IGListAdapter, didEndDisplaying sectionController: IGListSectionController, cell: UICollectionViewCell, at index: Int) { + let section = collectionContext!.section(for: self) + print("Did end displaying cell \(index) in section \(section)") + } + +} diff --git a/Example/IGListKitExamples/SectionControllers/EmbeddedSectionController.swift b/Example/IGListKitExamples/SectionControllers/EmbeddedSectionController.swift index 01f1bfcfd..682aa4518 100644 --- a/Example/IGListKitExamples/SectionControllers/EmbeddedSectionController.swift +++ b/Example/IGListKitExamples/SectionControllers/EmbeddedSectionController.swift @@ -15,7 +15,7 @@ import UIKit import IGListKit -class EmbeddedSectionController: IGListSectionController, IGListSectionType { +final class EmbeddedSectionController: IGListSectionController, IGListSectionType { var number: Int? diff --git a/Example/IGListKitExamples/SectionControllers/ExpandableSectionController.swift b/Example/IGListKitExamples/SectionControllers/ExpandableSectionController.swift index d4ed4520e..5389293a3 100644 --- a/Example/IGListKitExamples/SectionControllers/ExpandableSectionController.swift +++ b/Example/IGListKitExamples/SectionControllers/ExpandableSectionController.swift @@ -15,7 +15,7 @@ import UIKit import IGListKit -class ExpandableSectionController: IGListSectionController, IGListSectionType { +final class ExpandableSectionController: IGListSectionController, IGListSectionType { var expanded = false var object: String? diff --git a/Example/IGListKitExamples/SectionControllers/FeedItemSectionController.swift b/Example/IGListKitExamples/SectionControllers/FeedItemSectionController.swift new file mode 100644 index 000000000..5d58386cd --- /dev/null +++ b/Example/IGListKitExamples/SectionControllers/FeedItemSectionController.swift @@ -0,0 +1,69 @@ +/** + Copyright (c) 2016-present, Facebook, Inc. All rights reserved. + + The examples provided by Facebook are for non-commercial testing and evaluation + purposes only. Facebook reserves all rights not expressly granted. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +import IGListKit + +final class FeedItemSectionController: IGListSectionController, IGListSectionType, IGListSupplementaryViewSource { + + var feedItem: FeedItem! + + override init() { + super.init() + supplementaryViewSource = self + } + + // MARK: IGlistSectionType + + func numberOfItems() -> Int { + return feedItem.comments.count + } + + func sizeForItem(at index: Int) -> CGSize { + return CGSize(width: collectionContext!.containerSize.width, height: 55) + } + + func cellForItem(at index: Int) -> UICollectionViewCell { + let cell = collectionContext?.dequeueReusableCell(of: LabelCell.self, for: self, at: index) as! LabelCell + cell.label.text = feedItem.comments[index] + return cell + } + + func didUpdate(to object: Any) { + feedItem = object as? FeedItem + } + + func didSelectItem(at index: Int) {} + + // MARK: IGListSupplementaryViewSource + + func supportedElementKinds() -> [String] { + return [UICollectionElementKindSectionHeader] + } + + func viewForSupplementaryElement(ofKind elementKind: String, at index: Int) -> UICollectionReusableView { + let view = collectionContext?.dequeueReusableSupplementaryView(ofKind: UICollectionElementKindSectionHeader, + for: self, + nibName: "UserHeaderView", + bundle: nil, + at: index) as! UserHeaderView + view.handleLabel.text = "@" + feedItem.user.handle + view.nameLabel.text = feedItem.user.name + return view + } + + func sizeForSupplementaryView(ofKind elementKind: String, at index: Int) -> CGSize { + return CGSize(width: collectionContext!.containerSize.width, height: 40) + } + +} diff --git a/Example/IGListKitExamples/SectionControllers/GridSectionController.swift b/Example/IGListKitExamples/SectionControllers/GridSectionController.swift index 511e5f2f9..8d4f2ac04 100644 --- a/Example/IGListKitExamples/SectionControllers/GridSectionController.swift +++ b/Example/IGListKitExamples/SectionControllers/GridSectionController.swift @@ -27,7 +27,7 @@ class GridItem: NSObject { } -class GridSectionController: IGListSectionController, IGListSectionType { +final class GridSectionController: IGListSectionController, IGListSectionType { var object: GridItem? diff --git a/Example/IGListKitExamples/SectionControllers/HorizontalSectionController.swift b/Example/IGListKitExamples/SectionControllers/HorizontalSectionController.swift index 34be10fcc..4c5bad04e 100644 --- a/Example/IGListKitExamples/SectionControllers/HorizontalSectionController.swift +++ b/Example/IGListKitExamples/SectionControllers/HorizontalSectionController.swift @@ -15,7 +15,7 @@ import UIKit import IGListKit -class HorizontalSectionController: IGListSectionController, IGListSectionType, IGListAdapterDataSource { +final class HorizontalSectionController: IGListSectionController, IGListSectionType, IGListAdapterDataSource { var number: Int? diff --git a/Example/IGListKitExamples/SectionControllers/LabelSectionController.swift b/Example/IGListKitExamples/SectionControllers/LabelSectionController.swift index f139119ee..1dae09254 100644 --- a/Example/IGListKitExamples/SectionControllers/LabelSectionController.swift +++ b/Example/IGListKitExamples/SectionControllers/LabelSectionController.swift @@ -15,7 +15,7 @@ import UIKit import IGListKit -class LabelSectionController: IGListSectionController, IGListSectionType { +final class LabelSectionController: IGListSectionController, IGListSectionType { var object: String? diff --git a/Example/IGListKitExamples/SectionControllers/RemoveSectionController.swift b/Example/IGListKitExamples/SectionControllers/RemoveSectionController.swift index 8fd6273b2..e96d822e5 100644 --- a/Example/IGListKitExamples/SectionControllers/RemoveSectionController.swift +++ b/Example/IGListKitExamples/SectionControllers/RemoveSectionController.swift @@ -18,7 +18,7 @@ protocol RemoveSectionControllerDelegate: class { func removeSectionControllerWantsRemoved(_ sectionController: RemoveSectionController) } -class RemoveSectionController: IGListSectionController, IGListSectionType, RemoveCellDelegate { +final class RemoveSectionController: IGListSectionController, IGListSectionType, RemoveCellDelegate { weak var delegate: RemoveSectionControllerDelegate? var number: Int? diff --git a/Example/IGListKitExamples/SectionControllers/SearchSectionController.swift b/Example/IGListKitExamples/SectionControllers/SearchSectionController.swift index 7669723ab..087984edd 100644 --- a/Example/IGListKitExamples/SectionControllers/SearchSectionController.swift +++ b/Example/IGListKitExamples/SectionControllers/SearchSectionController.swift @@ -18,7 +18,7 @@ protocol SearchSectionControllerDelegate: class { func searchSectionController(_ sectionController: SearchSectionController, didChangeText text: String) } -class SearchSectionController: IGListSectionController, IGListSectionType, UISearchBarDelegate, IGListScrollDelegate { +final class SearchSectionController: IGListSectionController, IGListSectionType, UISearchBarDelegate, IGListScrollDelegate { weak var delegate: SearchSectionControllerDelegate? diff --git a/Example/IGListKitExamples/SectionControllers/SelfSizingSectionController.swift b/Example/IGListKitExamples/SectionControllers/SelfSizingSectionController.swift new file mode 100644 index 000000000..fe9575f52 --- /dev/null +++ b/Example/IGListKitExamples/SectionControllers/SelfSizingSectionController.swift @@ -0,0 +1,63 @@ +/** + Copyright (c) 2016-present, Facebook, Inc. All rights reserved. + + The examples provided by Facebook are for non-commercial testing and evaluation + purposes only. Facebook reserves all rights not expressly granted. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +import UIKit +import IGListKit + +final class SelfSizingSectionController: IGListSectionController, IGListSectionType { + + var model: SelectionModel! + + override init() { + super.init() + inset = UIEdgeInsets(top: 0, left: 0, bottom: 40, right: 0) + minimumLineSpacing = 4 + minimumInteritemSpacing = 4 + } + + func numberOfItems() -> Int { + return model.options.count + } + + func sizeForItem(at index: Int) -> CGSize { + return CGSize(width: collectionContext!.containerSize.width, height: 55) + } + + func cellForItem(at index: Int) -> UICollectionViewCell { + let text = model.options[index] + let cell: UICollectionViewCell + switch model.type { + case .none: + let manualCell = collectionContext!.dequeueReusableCell(of: ManuallySelfSizingCell.self, for: self, at: index) as! ManuallySelfSizingCell + manualCell.label.text = text + cell = manualCell + case .fullWidth: + let manualCell = collectionContext!.dequeueReusableCell(of: FullWidthSelfSizingCell.self, for: self, at: index) as! FullWidthSelfSizingCell + manualCell.label.text = text + cell = manualCell + case .nib: + let nibCell = collectionContext!.dequeueReusableCell(withNibName: "NibSelfSizingCell", bundle: nil, for: self, at: index) as! NibSelfSizingCell + nibCell.contentLabel.text = text + cell = nibCell + } + return cell + } + + func didUpdate(to object: Any) { + self.model = object as? SelectionModel + } + + func didSelectItem(at index: Int) {} + +} diff --git a/Example/IGListKitExamples/SectionControllers/StoryboardLabelSectionController.swift b/Example/IGListKitExamples/SectionControllers/StoryboardLabelSectionController.swift index 154401e29..331ca3e2c 100644 --- a/Example/IGListKitExamples/SectionControllers/StoryboardLabelSectionController.swift +++ b/Example/IGListKitExamples/SectionControllers/StoryboardLabelSectionController.swift @@ -15,7 +15,7 @@ import UIKit import IGListKit -class StoryboardLabelSectionController: IGListSectionController, IGListSectionType { +final class StoryboardLabelSectionController: IGListSectionController, IGListSectionType { var object: String? diff --git a/Example/IGListKitExamples/SectionControllers/UserSectionController.swift b/Example/IGListKitExamples/SectionControllers/UserSectionController.swift index eed891ded..1fa82764c 100644 --- a/Example/IGListKitExamples/SectionControllers/UserSectionController.swift +++ b/Example/IGListKitExamples/SectionControllers/UserSectionController.swift @@ -15,7 +15,7 @@ import UIKit import IGListKit -class UserSectionController: IGListSectionController, IGListSectionType { +final class UserSectionController: IGListSectionController, IGListSectionType { var user: User? diff --git a/Example/IGListKitExamples/SectionControllers/WorkingRangeSectionController.swift b/Example/IGListKitExamples/SectionControllers/WorkingRangeSectionController.swift index 4aeff0915..70703a1a3 100644 --- a/Example/IGListKitExamples/SectionControllers/WorkingRangeSectionController.swift +++ b/Example/IGListKitExamples/SectionControllers/WorkingRangeSectionController.swift @@ -15,7 +15,7 @@ import UIKit import IGListKit -class WorkingRangeSectionController: IGListSectionController, IGListSectionType, IGListWorkingRangeDelegate { +final class WorkingRangeSectionController: IGListSectionController, IGListSectionType, IGListWorkingRangeDelegate { var height: Int? var downloadedImage: UIImage? diff --git a/Example/Demo.storyboard b/Example/IGListKitExamples/Storyboard/Demo.storyboard similarity index 100% rename from Example/Demo.storyboard rename to Example/IGListKitExamples/Storyboard/Demo.storyboard diff --git a/Example/IGListKitExamples/ViewControllers/DemosViewController.swift b/Example/IGListKitExamples/ViewControllers/DemosViewController.swift index 80580da30..06a112767 100644 --- a/Example/IGListKitExamples/ViewControllers/DemosViewController.swift +++ b/Example/IGListKitExamples/ViewControllers/DemosViewController.swift @@ -15,7 +15,7 @@ import UIKit import IGListKit -class DemosViewController: UIViewController, IGListAdapterDataSource { +final class DemosViewController: UIViewController, IGListAdapterDataSource { lazy var adapter: IGListAdapter = { return IGListAdapter(updater: IGListAdapterUpdater(), viewController: self, workingRangeSize: 0) @@ -33,6 +33,9 @@ class DemosViewController: UIViewController, IGListAdapterDataSource { DemoItem(name: "Single Section Storyboard", controllerClass: SingleSectionViewController.self, controllerIdentifier: "singleSectionDemo"), DemoItem(name: "Working Range", controllerClass: WorkingRangeViewController.self), DemoItem(name: "Diff Algorithm", controllerClass: DiffTableViewController.self), + DemoItem(name: "Supplementary Views", controllerClass: SupplementaryViewController.self), + DemoItem(name: "Self-sizing cells", controllerClass: SelfSizingCellsViewController.self), + DemoItem(name: "Display delegate", controllerClass: DisplayViewController.self), ] override func viewDidLoad() { diff --git a/Example/IGListKitExamples/ViewControllers/DiffTableViewController.swift b/Example/IGListKitExamples/ViewControllers/DiffTableViewController.swift index ef7fbf134..23e29cd86 100644 --- a/Example/IGListKitExamples/ViewControllers/DiffTableViewController.swift +++ b/Example/IGListKitExamples/ViewControllers/DiffTableViewController.swift @@ -15,7 +15,7 @@ import UIKit import IGListKit -class Person: IGListDiffable { +final class Person: IGListDiffable { let pk: Int let name: String @@ -29,16 +29,14 @@ class Person: IGListDiffable { return pk as NSNumber } - func isEqual(_ object: IGListDiffable?) -> Bool { - if let object = object as? Person { - return self.name == object.name - } - return false + func isEqual(toDiffableObject object: IGListDiffable?) -> Bool { + guard let object = object as? Person else { return false } + return self.name == object.name } } -class DiffTableViewController: UITableViewController { +final class DiffTableViewController: UITableViewController { let oldPeople = [ Person(pk: 1, name: "Kevin"), @@ -86,9 +84,7 @@ class DiffTableViewController: UITableViewController { tableView.beginUpdates() tableView.deleteRows(at: result.deletes, with: .fade) tableView.insertRows(at: result.inserts, with: .fade) - for move in result.moves { - tableView.moveRow(at: move.from, to: move.to) - } + result.moves.forEach { tableView.moveRow(at: $0.from, to: $0.to) } tableView.endUpdates() } diff --git a/Example/IGListKitExamples/ViewControllers/DisplayViewController.swift b/Example/IGListKitExamples/ViewControllers/DisplayViewController.swift new file mode 100644 index 000000000..48ae94d33 --- /dev/null +++ b/Example/IGListKitExamples/ViewControllers/DisplayViewController.swift @@ -0,0 +1,49 @@ +/** + Copyright (c) 2016-present, Facebook, Inc. All rights reserved. + + The examples provided by Facebook are for non-commercial testing and evaluation + purposes only. Facebook reserves all rights not expressly granted. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +import UIKit +import IGListKit + +class DisplayViewController: UIViewController, IGListAdapterDataSource { + + lazy var adapter: IGListAdapter = { + return IGListAdapter(updater: IGListAdapterUpdater(), viewController: self, workingRangeSize: 0) + }() + let collectionView = IGListCollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) + + override func viewDidLoad() { + super.viewDidLoad() + view.addSubview(collectionView) + adapter.collectionView = collectionView + adapter.dataSource = self + } + + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + collectionView.frame = view.bounds + } + + // MARK: IGListAdapterDataSource + + func objects(for listAdapter: IGListAdapter) -> [IGListDiffable] { + return [1, 2, 3, 4, 5, 6] as [NSNumber] + } + + func listAdapter(_ listAdapter: IGListAdapter, sectionControllerFor object: Any) -> IGListSectionController { + return DisplaySectionController() + } + + func emptyView(for listAdapter: IGListAdapter) -> UIView? { return nil } + +} diff --git a/Example/IGListKitExamples/ViewControllers/EmptyViewController.swift b/Example/IGListKitExamples/ViewControllers/EmptyViewController.swift index 46d45e2f1..beb3cebec 100644 --- a/Example/IGListKitExamples/ViewControllers/EmptyViewController.swift +++ b/Example/IGListKitExamples/ViewControllers/EmptyViewController.swift @@ -15,7 +15,7 @@ import UIKit import IGListKit -class EmptyViewController: UIViewController, IGListAdapterDataSource, RemoveSectionControllerDelegate { +final class EmptyViewController: UIViewController, IGListAdapterDataSource, RemoveSectionControllerDelegate { lazy var adapter: IGListAdapter = { return IGListAdapter(updater: IGListAdapterUpdater(), viewController: self, workingRangeSize: 0) diff --git a/Example/IGListKitExamples/ViewControllers/LoadMoreViewController.swift b/Example/IGListKitExamples/ViewControllers/LoadMoreViewController.swift index f5eacf2f4..8d988102d 100644 --- a/Example/IGListKitExamples/ViewControllers/LoadMoreViewController.swift +++ b/Example/IGListKitExamples/ViewControllers/LoadMoreViewController.swift @@ -15,7 +15,7 @@ import UIKit import IGListKit -class LoadMoreViewController: UIViewController, IGListAdapterDataSource, UIScrollViewDelegate { +final class LoadMoreViewController: UIViewController, IGListAdapterDataSource, UIScrollViewDelegate { lazy var adapter: IGListAdapter = { return IGListAdapter(updater: IGListAdapterUpdater(), viewController: self, workingRangeSize: 0) @@ -68,7 +68,7 @@ class LoadMoreViewController: UIViewController, IGListAdapterDataSource, UIScrol if !loading && distance < 200 { loading = true adapter.performUpdates(animated: true, completion: nil) - DispatchQueue.global(qos: .default).async(execute: { + DispatchQueue.global(qos: .default).async { // fake background loading task sleep(2) DispatchQueue.main.async { @@ -77,7 +77,7 @@ class LoadMoreViewController: UIViewController, IGListAdapterDataSource, UIScrol self.items.append(contentsOf: Array(itemCount.. [IGListDiffable] { + return data as [IGListDiffable] + } + + func listAdapter(_ listAdapter: IGListAdapter, sectionControllerFor object: Any) -> IGListSectionController { + return SelfSizingSectionController() + } + + func emptyView(for listAdapter: IGListAdapter) -> UIView? { return nil } + +} diff --git a/Example/IGListKitExamples/ViewControllers/SingleSectionStoryboardViewController.swift b/Example/IGListKitExamples/ViewControllers/SingleSectionStoryboardViewController.swift index 045c6cb86..45a8a0f4f 100644 --- a/Example/IGListKitExamples/ViewControllers/SingleSectionStoryboardViewController.swift +++ b/Example/IGListKitExamples/ViewControllers/SingleSectionStoryboardViewController.swift @@ -40,11 +40,11 @@ final class SingleSectionStoryboardViewController: UIViewController, IGListAdapt } func listAdapter(_ listAdapter: IGListAdapter, sectionControllerFor object: Any) -> IGListSectionController { - let configureBlock = { (data: Any, cell: UICollectionViewCell) in - guard let cell = cell as? StoryboardCell, let number = data as? Int else { return } + let configureBlock = { (item: Any, cell: UICollectionViewCell) in + guard let cell = cell as? StoryboardCell, let number = item as? Int else { return } cell.textLabel.text = "Cell: \(number + 1)" } - let sizeBlock = { (context: IGListCollectionContext?) -> CGSize in + let sizeBlock = { (item: Any, context: IGListCollectionContext?) -> CGSize in guard let context = context else { return .zero } return CGSize(width: context.containerSize.width, height: 44) } diff --git a/Example/IGListKitExamples/ViewControllers/SingleSectionViewController.swift b/Example/IGListKitExamples/ViewControllers/SingleSectionViewController.swift index 782706b91..eb9f4b510 100644 --- a/Example/IGListKitExamples/ViewControllers/SingleSectionViewController.swift +++ b/Example/IGListKitExamples/ViewControllers/SingleSectionViewController.swift @@ -47,12 +47,12 @@ final class SingleSectionViewController: UIViewController, IGListAdapterDataSour } func listAdapter(_ listAdapter: IGListAdapter, sectionControllerFor object: Any) -> IGListSectionController { - let configureBlock = { (data: Any, cell: UICollectionViewCell) in - guard let cell = cell as? NibCell, let number = data as? Int else { return } + let configureBlock = { (item: Any, cell: UICollectionViewCell) in + guard let cell = cell as? NibCell, let number = item as? Int else { return } cell.textLabel.text = "Cell: \(number + 1)" } - let sizeBlock = { (context: IGListCollectionContext?) -> CGSize in + let sizeBlock = { (item: Any, context: IGListCollectionContext?) -> CGSize in guard let context = context else { return CGSize() } return CGSize(width: context.containerSize.width, height: 44) } diff --git a/Example/IGListKitExamples/ViewControllers/StoryboardViewController.swift b/Example/IGListKitExamples/ViewControllers/StoryboardViewController.swift index 38b006514..f31aece2a 100644 --- a/Example/IGListKitExamples/ViewControllers/StoryboardViewController.swift +++ b/Example/IGListKitExamples/ViewControllers/StoryboardViewController.swift @@ -15,7 +15,7 @@ import UIKit import IGListKit -class StoryboardViewController: UIViewController, IGListAdapterDataSource { +final class StoryboardViewController: UIViewController, IGListAdapterDataSource { @IBOutlet weak var collectionView: IGListCollectionView! diff --git a/Example/IGListKitExamples/ViewControllers/SupplementaryViewController.swift b/Example/IGListKitExamples/ViewControllers/SupplementaryViewController.swift new file mode 100644 index 000000000..a66ced311 --- /dev/null +++ b/Example/IGListKitExamples/ViewControllers/SupplementaryViewController.swift @@ -0,0 +1,56 @@ +/** + Copyright (c) 2016-present, Facebook, Inc. All rights reserved. + + The examples provided by Facebook are for non-commercial testing and evaluation + purposes only. Facebook reserves all rights not expressly granted. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +import UIKit +import IGListKit + +final class SupplementaryViewController: UIViewController, IGListAdapterDataSource { + + lazy var adapter: IGListAdapter = { + return IGListAdapter(updater: IGListAdapterUpdater(), viewController: self, workingRangeSize: 0) + }() + let collectionView = IGListCollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) + + let feedItems = [ + FeedItem(pk: 1, user: User(pk: 100, name: "Jesse", handle: "jesse_squires"), comments: ["You rock!", "Hmm you sure about that?"]), + FeedItem(pk: 2, user: User(pk: 101, name: "Ryan", handle: "_ryannystrom"), comments: ["lgtm", "lol", "Let's try it!"]), + FeedItem(pk: 3, user: User(pk: 102, name: "Ann", handle: "abaum"), comments: ["Good luck!"]), + FeedItem(pk: 4, user: User(pk: 103, name: "Phil", handle: "phil"), comments: ["yoooooooo", "What's the eta?"]), + ] + + override func viewDidLoad() { + super.viewDidLoad() + view.addSubview(collectionView) + adapter.collectionView = collectionView + adapter.dataSource = self + } + + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + collectionView.frame = view.bounds + } + + // MARK: IGListAdapterDataSource + + func objects(for listAdapter: IGListAdapter) -> [IGListDiffable] { + return feedItems + } + + func listAdapter(_ listAdapter: IGListAdapter, sectionControllerFor object: Any) -> IGListSectionController { + return FeedItemSectionController() + } + + func emptyView(for listAdapter: IGListAdapter) -> UIView? { return nil } + +} diff --git a/Example/IGListKitExamples/ViewControllers/WorkingRangeViewController.swift b/Example/IGListKitExamples/ViewControllers/WorkingRangeViewController.swift index a25a2f0d3..a4232a49b 100644 --- a/Example/IGListKitExamples/ViewControllers/WorkingRangeViewController.swift +++ b/Example/IGListKitExamples/ViewControllers/WorkingRangeViewController.swift @@ -15,7 +15,7 @@ import UIKit import IGListKit -class WorkingRangeViewController: UIViewController, IGListAdapterDataSource { +final class WorkingRangeViewController: UIViewController, IGListAdapterDataSource { lazy var adapter: IGListAdapter = { return IGListAdapter(updater: IGListAdapterUpdater(), viewController: self, workingRangeSize: 2) diff --git a/Example/IGListKitExamples/Views/FullWidthSelfSizingCell.swift b/Example/IGListKitExamples/Views/FullWidthSelfSizingCell.swift new file mode 100644 index 000000000..508401f1d --- /dev/null +++ b/Example/IGListKitExamples/Views/FullWidthSelfSizingCell.swift @@ -0,0 +1,55 @@ +/** + Copyright (c) 2016-present, Facebook, Inc. All rights reserved. + + The examples provided by Facebook are for non-commercial testing and evaluation + purposes only. Facebook reserves all rights not expressly granted. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +import UIKit + +final class FullWidthSelfSizingCell: UICollectionViewCell { + + let label: UILabel = { + let label = UILabel() + label.backgroundColor = UIColor.red.withAlphaComponent(0.1) + label.numberOfLines = 0 + label.translatesAutoresizingMaskIntoConstraints = false + return label + }() + + override init(frame: CGRect) { + super.init(frame: frame) + + contentView.backgroundColor = .white + + contentView.addSubview(label) + + NSLayoutConstraint(item: label, attribute: .top, relatedBy: .equal, toItem: contentView, attribute: .top, multiplier: 1, constant: 15).isActive = true + NSLayoutConstraint(item: label, attribute: .leading, relatedBy: .equal, toItem: contentView, attribute: .leading, multiplier: 1, constant: 15).isActive = true + NSLayoutConstraint(item: contentView, attribute: .bottom, relatedBy: .equal, toItem: label, attribute: .bottom, multiplier: 1, constant: 15).isActive = true + NSLayoutConstraint(item: contentView, attribute: .trailing, relatedBy: .equal, toItem: label, attribute: .trailing, multiplier: 1, constant: 15).isActive = true + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes { + setNeedsLayout() + layoutIfNeeded() + let size = contentView.systemLayoutSizeFitting(layoutAttributes.size) + var newFrame = layoutAttributes.frame + // note: don't change the width + newFrame.size.height = ceil(size.height) + layoutAttributes.frame = newFrame + return layoutAttributes + } + +} diff --git a/Example/IGListKitExamples/Views/ManuallySelfSizingCell.swift b/Example/IGListKitExamples/Views/ManuallySelfSizingCell.swift new file mode 100644 index 000000000..7883ea18c --- /dev/null +++ b/Example/IGListKitExamples/Views/ManuallySelfSizingCell.swift @@ -0,0 +1,55 @@ +/** + Copyright (c) 2016-present, Facebook, Inc. All rights reserved. + + The examples provided by Facebook are for non-commercial testing and evaluation + purposes only. Facebook reserves all rights not expressly granted. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +import UIKit + +class ManuallySelfSizingCell: UICollectionViewCell { + + let label: UILabel = { + let label = UILabel() + label.backgroundColor = UIColor.green.withAlphaComponent(0.1) + label.numberOfLines = 1 + label.translatesAutoresizingMaskIntoConstraints = false + return label + }() + + override init(frame: CGRect) { + super.init(frame: frame) + + contentView.backgroundColor = .white + + contentView.addSubview(label) + + NSLayoutConstraint(item: label, attribute: .top, relatedBy: .equal, toItem: contentView, attribute: .top, multiplier: 1, constant: 15).isActive = true + NSLayoutConstraint(item: label, attribute: .leading, relatedBy: .equal, toItem: contentView, attribute: .leading, multiplier: 1, constant: 15).isActive = true + NSLayoutConstraint(item: contentView, attribute: .bottom, relatedBy: .equal, toItem: label, attribute: .bottom, multiplier: 1, constant: 15).isActive = true + NSLayoutConstraint(item: contentView, attribute: .trailing, relatedBy: .equal, toItem: label, attribute: .trailing, multiplier: 1, constant: 15).isActive = true + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes { + setNeedsLayout() + layoutIfNeeded() + let size = contentView.systemLayoutSizeFitting(layoutAttributes.size) + var newFrame = layoutAttributes.frame + newFrame.size.width = ceil(size.width) + newFrame.size.height = ceil(size.height) + layoutAttributes.frame = newFrame + return layoutAttributes + } + +} diff --git a/Example/IGListKitExamples/Views/NibSelfSizingCell.swift b/Example/IGListKitExamples/Views/NibSelfSizingCell.swift new file mode 100644 index 000000000..dc454f9c2 --- /dev/null +++ b/Example/IGListKitExamples/Views/NibSelfSizingCell.swift @@ -0,0 +1,21 @@ +/** + Copyright (c) 2016-present, Facebook, Inc. All rights reserved. + + The examples provided by Facebook are for non-commercial testing and evaluation + purposes only. Facebook reserves all rights not expressly granted. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +import UIKit + +class NibSelfSizingCell: UICollectionViewCell { + + @IBOutlet weak var contentLabel: UILabel! + +} diff --git a/Example/IGListKitExamples/Views/NibSelfSizingCell.xib b/Example/IGListKitExamples/Views/NibSelfSizingCell.xib new file mode 100644 index 000000000..ffacfac7c --- /dev/null +++ b/Example/IGListKitExamples/Views/NibSelfSizingCell.xib @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example/IGListKitExamples/Views/SpinnerCell.swift b/Example/IGListKitExamples/Views/SpinnerCell.swift index 3a800ed1d..b7e84a9ea 100644 --- a/Example/IGListKitExamples/Views/SpinnerCell.swift +++ b/Example/IGListKitExamples/Views/SpinnerCell.swift @@ -21,7 +21,7 @@ func spinnerSectionController() -> IGListSingleSectionController { cell.activityIndicator.startAnimating() } - let sizeBlock = { (context: IGListCollectionContext?) -> CGSize in + let sizeBlock = { (item: Any, context: IGListCollectionContext?) -> CGSize in guard let context = context else { return .zero } return CGSize(width: context.containerSize.width, height: 100) } diff --git a/Example/IGListKitExamples/Views/UserHeaderView.swift b/Example/IGListKitExamples/Views/UserHeaderView.swift new file mode 100644 index 000000000..190de56b6 --- /dev/null +++ b/Example/IGListKitExamples/Views/UserHeaderView.swift @@ -0,0 +1,22 @@ +/** + Copyright (c) 2016-present, Facebook, Inc. All rights reserved. + + The examples provided by Facebook are for non-commercial testing and evaluation + purposes only. Facebook reserves all rights not expressly granted. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +import UIKit + +final class UserHeaderView: UICollectionViewCell { + + @IBOutlet weak var nameLabel: UILabel! + @IBOutlet weak var handleLabel: UILabel! + +} diff --git a/Example/IGListKitExamples/Views/UserHeaderView.xib b/Example/IGListKitExamples/Views/UserHeaderView.xib new file mode 100644 index 000000000..9453ef356 --- /dev/null +++ b/Example/IGListKitExamples/Views/UserHeaderView.xib @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example/IGListKitMessageExample/Assets.xcassets/Contents.json b/Example/IGListKitMessageExample/Assets.xcassets/Contents.json new file mode 100644 index 000000000..da4a164c9 --- /dev/null +++ b/Example/IGListKitMessageExample/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Example/IGListKitMessageExample/Assets.xcassets/iMessage App Icon.stickersiconset/Contents.json b/Example/IGListKitMessageExample/Assets.xcassets/iMessage App Icon.stickersiconset/Contents.json new file mode 100644 index 000000000..22c2afeb4 --- /dev/null +++ b/Example/IGListKitMessageExample/Assets.xcassets/iMessage App Icon.stickersiconset/Contents.json @@ -0,0 +1,58 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "60x45", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x45", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "67x50", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "74x55", + "scale" : "2x" + }, + { + "size" : "27x20", + "idiom" : "universal", + "scale" : "2x", + "platform" : "ios" + }, + { + "size" : "27x20", + "idiom" : "universal", + "scale" : "3x", + "platform" : "ios" + }, + { + "size" : "32x24", + "idiom" : "universal", + "scale" : "2x", + "platform" : "ios" + }, + { + "size" : "32x24", + "idiom" : "universal", + "scale" : "3x", + "platform" : "ios" + }, + { + "size" : "1024x768", + "idiom" : "ios-marketing", + "scale" : "1x", + "platform" : "ios" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Example/IGListKitMessageExample/Info.plist b/Example/IGListKitMessageExample/Info.plist new file mode 100644 index 000000000..28e2e1af3 --- /dev/null +++ b/Example/IGListKitMessageExample/Info.plist @@ -0,0 +1,31 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + IGListKit + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + XPC! + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + NSExtension + + NSExtensionPointIdentifier + com.apple.message-payload-provider + NSExtensionPrincipalClass + IGListKitMessageExample.MessagesViewController + + + diff --git a/Example/IGListKitMessageExample/MessagesViewController.swift b/Example/IGListKitMessageExample/MessagesViewController.swift new file mode 100644 index 000000000..858c48a17 --- /dev/null +++ b/Example/IGListKitMessageExample/MessagesViewController.swift @@ -0,0 +1,59 @@ +/** + Copyright (c) 2016-present, Facebook, Inc. All rights reserved. + + The examples provided by Facebook are for non-commercial testing and evaluation + purposes only. Facebook reserves all rights not expressly granted. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +import UIKit +import Messages +import IGListKit + +final class MessagesViewController: MSMessagesAppViewController, IGListAdapterDataSource { + + lazy var adapter: IGListAdapter = { + return IGListAdapter(updater: IGListAdapterUpdater(), viewController: self, workingRangeSize: 0) + }() + let collectionView = IGListCollectionView(frame: CGRect.zero, collectionViewLayout: UICollectionViewFlowLayout()) + + let data = "Maecenas faucibus mollis interdum. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit.".components(separatedBy: " ") + + override func viewDidLoad() { + super.viewDidLoad() + + adapter.collectionView = collectionView + adapter.dataSource = self + + view.addSubview(collectionView) + } + + override func loadView() { + view = UIView(frame: CGRect(x: 0, y: 0, width: 320, height: 200)) + } + + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + collectionView.frame = view.bounds + } + + // MARK: IGListAdapterDataSource + + func objects(for listAdapter: IGListAdapter) -> [IGListDiffable] { + return data as [IGListDiffable] + } + + func listAdapter(_ listAdapter: IGListAdapter, sectionControllerFor object: Any) -> IGListSectionController { + return LabelSectionController() + } + + func emptyView(for listAdapter: IGListAdapter) -> UIView? { + return nil + } +} diff --git a/Example/IGListKitTodayExample/Info.plist b/Example/IGListKitTodayExample/Info.plist new file mode 100644 index 000000000..7e8424b8f --- /dev/null +++ b/Example/IGListKitTodayExample/Info.plist @@ -0,0 +1,31 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + IGListKit + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + XPC! + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + NSExtension + + NSExtensionPointIdentifier + com.apple.widget-extension + NSExtensionPrincipalClass + IGListKitTodayExample.TodayViewController + + + diff --git a/Example/IGListKitTodayExample/TodayViewController.swift b/Example/IGListKitTodayExample/TodayViewController.swift new file mode 100644 index 000000000..b8102ca3b --- /dev/null +++ b/Example/IGListKitTodayExample/TodayViewController.swift @@ -0,0 +1,70 @@ +/** + Copyright (c) 2016-present, Facebook, Inc. All rights reserved. + + The examples provided by Facebook are for non-commercial testing and evaluation + purposes only. Facebook reserves all rights not expressly granted. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +import UIKit +import NotificationCenter +import IGListKit + +@available(iOSApplicationExtension 10.0, *) +final class TodayViewController: UIViewController, NCWidgetProviding, IGListAdapterDataSource { + + lazy var adapter: IGListAdapter = { + return IGListAdapter(updater: IGListAdapterUpdater(), viewController: self, workingRangeSize: 0) + }() + let collectionView = IGListCollectionView(frame: CGRect.zero, collectionViewLayout: UICollectionViewFlowLayout()) + + let data = "Maecenas faucibus mollis interdum. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit.".components(separatedBy: " ") + + override func viewDidLoad() { + super.viewDidLoad() + + adapter.collectionView = collectionView + adapter.dataSource = self + + view.addSubview(collectionView) + + // Enables the 'Show More' button in the widget interface + extensionContext?.widgetLargestAvailableDisplayMode = .expanded + } + + + override func loadView() { + view = UIView(frame: CGRect(x: 0, y: 0, width: 320, height: 110)) + } + + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + collectionView.frame = view.bounds + } + + // MARK: NCWidgetProviding + + func widgetActiveDisplayModeDidChange(_ activeDisplayMode: NCWidgetDisplayMode, withMaximumSize maxSize: CGSize) { + preferredContentSize = maxSize + } + + // MARK: IGListAdapterDataSource + + func objects(for listAdapter: IGListAdapter) -> [IGListDiffable] { + return data as [IGListDiffable] + } + + func listAdapter(_ listAdapter: IGListAdapter, sectionControllerFor object: Any) -> IGListSectionController { + return LabelSectionController() + } + + func emptyView(for listAdapter: IGListAdapter) -> UIView? { + return nil + } +} diff --git a/Example/Podfile b/Example/Podfile index 6f869695f..3c097bbd1 100644 --- a/Example/Podfile +++ b/Example/Podfile @@ -2,4 +2,12 @@ use_frameworks! target 'IGListKitExamples' do pod 'IGListKit', :path => '../IGListKit.podspec' +end + +target 'IGListKitMessageExample' do + pod 'IGListKit', :path => '../IGListKit.podspec' +end + +target 'IGListKitTodayExample' do + pod 'IGListKit', :path => '../IGListKit.podspec' end \ No newline at end of file diff --git a/Example/Podfile.lock b/Example/Podfile.lock index 6018bbd37..fe4c8c6c9 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -9,8 +9,8 @@ EXTERNAL SOURCES: :path: ../IGListKit.podspec SPEC CHECKSUMS: - IGListKit: 3242c475fa77e2abf2d4de319703088008fbe9b9 + IGListKit: a534a917b574ec56697390ef182f125ccff2145b -PODFILE CHECKSUM: 4bdfb42d1e7b2b121bf8c83bc300d7d77aa0fc3a +PODFILE CHECKSUM: cc1e0cbb39e7099e1bd4ec1453b7e5a63c1af10d -COCOAPODS: 1.1.0.rc.3 +COCOAPODS: 1.1.1 diff --git a/Example/Pods/Local Podspecs/IGListKit.podspec.json b/Example/Pods/Local Podspecs/IGListKit.podspec.json index 04de4c67e..9e6054f95 100644 --- a/Example/Pods/Local Podspecs/IGListKit.podspec.json +++ b/Example/Pods/Local Podspecs/IGListKit.podspec.json @@ -19,7 +19,8 @@ "private_header_files": "Source/Internal/*.h", "requires_arc": true, "platforms": { - "ios": "8.0" + "ios": "8.0", + "tvos": "9.0" }, "frameworks": "UIKit", "libraries": "c++", diff --git a/Example/Pods/Manifest.lock b/Example/Pods/Manifest.lock index 6018bbd37..fe4c8c6c9 100644 --- a/Example/Pods/Manifest.lock +++ b/Example/Pods/Manifest.lock @@ -9,8 +9,8 @@ EXTERNAL SOURCES: :path: ../IGListKit.podspec SPEC CHECKSUMS: - IGListKit: 3242c475fa77e2abf2d4de319703088008fbe9b9 + IGListKit: a534a917b574ec56697390ef182f125ccff2145b -PODFILE CHECKSUM: 4bdfb42d1e7b2b121bf8c83bc300d7d77aa0fc3a +PODFILE CHECKSUM: cc1e0cbb39e7099e1bd4ec1453b7e5a63c1af10d -COCOAPODS: 1.1.0.rc.3 +COCOAPODS: 1.1.1 diff --git a/Example/Pods/Pods.xcodeproj/project.pbxproj b/Example/Pods/Pods.xcodeproj/project.pbxproj index ea358414c..c9cbf85fc 100644 --- a/Example/Pods/Pods.xcodeproj/project.pbxproj +++ b/Example/Pods/Pods.xcodeproj/project.pbxproj @@ -7,190 +7,242 @@ objects = { /* Begin PBXBuildFile section */ - 0147435D65030952AE49DEC4E017B23D /* UICollectionView+IGListBatchUpdateData.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E99717CDC2053D36C6789D1148FB800 /* UICollectionView+IGListBatchUpdateData.m */; }; - 026755843D7FB53E35679B703EFBBF6E /* IGListSectionMap.m in Sources */ = {isa = PBXBuildFile; fileRef = BA166501E81C4BA1DF5A400979E86CDB /* IGListSectionMap.m */; }; - 084B851CFFA9C0E2DF68D903E53E0EC8 /* IGListAssert.h in Headers */ = {isa = PBXBuildFile; fileRef = 5317DB3BAAEE0CC7B2D2B105A879060D /* IGListAssert.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 0C27A4BED7FE0607F8E864854B0D4CB4 /* IGListIndexPathResultInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 7377305092E6A1E16624C7EBA4782FED /* IGListIndexPathResultInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 135EAE77737104157F6CC0655BBA0ABA /* IGListSectionController.m in Sources */ = {isa = PBXBuildFile; fileRef = F5AD8343AC8B755A3258D6E45FFD2D8A /* IGListSectionController.m */; }; - 1691094821EAD389A7A9C0BA79A970DB /* IGListIndexSetResultInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = B4D067AEE0F5C07151A19715FCE108F3 /* IGListIndexSetResultInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 171501700F6A914CD4C44E3666398BB5 /* IGListAdapterProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E2D3628C46D46E7D75C2D9C65C0C6E7 /* IGListAdapterProxy.m */; }; - 1CCB2FEACC2123958F5A0E39F70659B5 /* IGListDisplayHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = D3934C6500E5C7C907F1AC3B6C1AF15C /* IGListDisplayHandler.m */; }; - 1EB6675BEF69B9E921CE4199DD7156D0 /* IGListAdapterInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = DC277CBFF0D26310BEA0C5603C4EAA45 /* IGListAdapterInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 1FD624CB427ECAEF7F1F9949E4B023AE /* IGListUpdatingDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 5074228D8F3A063BF5EE38BBCDC854D8 /* IGListUpdatingDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 213FF484E5786DD35F2A932774C57707 /* IGListSingleSectionController.m in Sources */ = {isa = PBXBuildFile; fileRef = 91007FC1F36EE50D4609909509B4BE04 /* IGListSingleSectionController.m */; }; - 25FDCBDCEA5575091B36BFE4B59D04CA /* IGListDiff.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B14381CF1C8B474F904BED10858A3B1 /* IGListDiff.mm */; }; - 26750C29F741D0EF22EF396017265DC7 /* IGListSupplementaryViewSource.h in Headers */ = {isa = PBXBuildFile; fileRef = D7D841899F69CAEFE9CC75F4C742EB7F /* IGListSupplementaryViewSource.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 28063C0E5F9119F809C37919575A132F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A2A6FF208CEC4C2861F1E9D42D651453 /* Foundation.framework */; }; - 2912A571DF503B64C589EC9A44BA4B39 /* IGListIndexPathResult.m in Sources */ = {isa = PBXBuildFile; fileRef = DD1EB6F6A5F5CF2DA79688B3A01F95BC /* IGListIndexPathResult.m */; }; - 2C58ED7F6EFFB13891EBAAF768E2C998 /* IGListSingleSectionController.h in Headers */ = {isa = PBXBuildFile; fileRef = A6A48D5B55D7631327C124F538C6E068 /* IGListSingleSectionController.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 32DA59CCC51F3C4A5239E87A45351EEE /* IGListMoveIndexPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F401C4ED6FD8A5953382E94BFDC1B04 /* IGListMoveIndexPath.m */; }; - 35102F69615549F427FE2EC453149DAB /* IGListAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 73259AA7FEA14577AEF2DB550C3020EB /* IGListAdapter.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 419BBEB1F205EA82FF1A300B6E954F7D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A2A6FF208CEC4C2861F1E9D42D651453 /* Foundation.framework */; }; - 444D6A0E181DF93311717CA41DB7B48A /* IGListMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E7FEF0C49C387ED472744AB5E63D5C5 /* IGListMacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 4C6CC1B183686EB9EE4A7FF40CAFF697 /* IGListCollectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B5597025F567F3628A6FE6AB07D53F3 /* IGListCollectionView.m */; }; - 4CCFD8A322D6F78F55604A0E638FE191 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E86668F20F252C440D1015B816BE59C5 /* UIKit.framework */; }; - 503BDC35E6053B83D862316F3D8C935F /* IGListDiff.h in Headers */ = {isa = PBXBuildFile; fileRef = B3A4D0DCC742ED05F9B0EAD98B483829 /* IGListDiff.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 5455F7C71EB93A534D8A09AAFE8EF0FE /* IGListBatchUpdateData.mm in Sources */ = {isa = PBXBuildFile; fileRef = D0AEE94B91F9849EEF961CC1C265C985 /* IGListBatchUpdateData.mm */; }; - 54CFA8A4442E7B0BB4C67FE811481E4C /* IGListMoveIndex.m in Sources */ = {isa = PBXBuildFile; fileRef = D37ACDCF54F63073142D7196E56946A3 /* IGListMoveIndex.m */; }; - 54E0CADE21353023E6F071C5FB164902 /* IGListStackedSectionController.m in Sources */ = {isa = PBXBuildFile; fileRef = 22F3AD163D43B95418E4F734FDD061F4 /* IGListStackedSectionController.m */; }; - 54EAA3B5C88905CD01B5FE2ADDF92FC6 /* IGListMoveIndexPathInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 8D8C265CA74986A39B9EF8127AE0349D /* IGListMoveIndexPathInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 57FF7C6AED54D8A04C41DA36231BFC94 /* IGListStackedSectionController.h in Headers */ = {isa = PBXBuildFile; fileRef = B9B2C760A6B8BC4E2F9B9BC221585A06 /* IGListStackedSectionController.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6110D5294C734F5AF8FAF5AD4134789F /* IGListSectionControllerInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 928F8C884AA9FD0FBF674F4CF5DAC4D8 /* IGListSectionControllerInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 623527A4232D59FB38547902423B5AA2 /* IGListCollectionContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 17FC1649F3BE2A7A920FF0C7D50B7EC2 /* IGListCollectionContext.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 68A93F0E164CD1E9910C25698B5B0DC7 /* IGListAdapterProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 109159D72077E46327880D41EE69B804 /* IGListAdapterProxy.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 6B2EE19479243F984CE51F15ACCB1A33 /* IGListAdapterDataSource.h in Headers */ = {isa = PBXBuildFile; fileRef = FE4F9D5E24C8E166CBE1324FB4EFE901 /* IGListAdapterDataSource.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6C43A407033E5A273E9E16EE7E334EB2 /* IGListSectionType.h in Headers */ = {isa = PBXBuildFile; fileRef = C0D34FDB422AF09AA6F7813D34DA3DCD /* IGListSectionType.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6F06EF99F8A0B55F4E81D767EB7F4B36 /* IGListMoveIndexPath.h in Headers */ = {isa = PBXBuildFile; fileRef = A25B427B6865597BD60B14637B4DF317 /* IGListMoveIndexPath.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 725B0E02B9D828F61443072352992F54 /* IGListWorkingRangeHandler.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0103D32BB7A0A6165DCA97AE90B78FF3 /* IGListWorkingRangeHandler.mm */; }; - 76B403D7072D98BED2AA6AA6C7827E39 /* IGListAdapterDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 8C9AC4FA89437FC74B5044CB6E09F330 /* IGListAdapterDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 80AB64741918F4F2A7585C3C5FCBD98D /* IGListCollectionView.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FE4AA45BC45A8EF0F9FB575B19EE801 /* IGListCollectionView.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 83E3217B930A28021BC1DFC1DFD759A0 /* IGListWorkingRangeDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = D9F947E7710011A32E4FA3C988472760 /* IGListWorkingRangeDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 86B79ED8B51A8D5353E49A6C37DFE5CB /* IGListMoveIndexInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 7ADB9063D305B8288C4BB24BC56A463F /* IGListMoveIndexInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 86BA72487680B4F3CFEB719F821D183A /* IGListWorkingRangeHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F1AA350148ECB86D3C7EAA99E50E71E /* IGListWorkingRangeHandler.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 8F026EF7A1AB975A5411D2BDE5B4C081 /* IGListMoveIndex.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F331B7F935DA82F2BA8F9EC9CDAC989 /* IGListMoveIndex.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 931AB3AD8B295F26EDDB6FC6849EA247 /* IGListIndexSetResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 84752D2DDFC17301AD69B035A1ABEB98 /* IGListIndexSetResult.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 9368BAE80054E3977919DCC164581318 /* UICollectionView+IGListBatchUpdateData.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F7D2957E3E38FF3DDE6BDE4FB7B5599 /* UICollectionView+IGListBatchUpdateData.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 9EA7B904CC4B3E23C79B9B3909A51C2A /* IGListIndexPathResult.h in Headers */ = {isa = PBXBuildFile; fileRef = DBA04B01FE70BC1FC9B2AF5A04816653 /* IGListIndexPathResult.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 9F9C5D1351A6EB88531F759304A7A5D6 /* IGListSectionController.h in Headers */ = {isa = PBXBuildFile; fileRef = 50D66D11EB993B3B287DA0B8DEE153B7 /* IGListSectionController.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A01D6F5340CA1BD84E5DAB81B60A02A2 /* IGListDiffable.h in Headers */ = {isa = PBXBuildFile; fileRef = 54A169D9E10ABA4A657E466A81CF5E96 /* IGListDiffable.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A6091B575605FDBAD5E9E5645248FD66 /* IGListAdapterUpdaterDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 923F1BE703C78DB09D0F325460A4A2EA /* IGListAdapterUpdaterDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; - B01F1324E6269028CE385E78C26EF9D3 /* IGListDisplayHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 0446A9446334650F8C62E86A0E6E53A3 /* IGListDisplayHandler.h */; settings = {ATTRIBUTES = (Private, ); }; }; - B17B8BA5347B0717A112EB2BCE055293 /* IGListExperiments.h in Headers */ = {isa = PBXBuildFile; fileRef = 8CFC4E4785DC5CD494D3BA69EE0EF1C5 /* IGListExperiments.h */; settings = {ATTRIBUTES = (Public, ); }; }; - B70560D9E6761A6E5666060E05DE071C /* IGListStackedSectionControllerInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = DD4F28A7CC1A638EF87DA9D5583C4CAA /* IGListStackedSectionControllerInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; - B7FADDD58154CEA589481E450BD88E33 /* Pods-IGListKitExamples-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F5AE0385534EC7E6CA75003A7280492 /* Pods-IGListKitExamples-dummy.m */; }; - BA98207EA92AA990BE64F3C8970CBC9A /* NSObject+IGListDiffable.m in Sources */ = {isa = PBXBuildFile; fileRef = 720FAF43FD40FA27160DB53AD4C8E73D /* NSObject+IGListDiffable.m */; }; - BAB517802021813C296E2F2BA2C91FE2 /* IGListAdapterUpdater.h in Headers */ = {isa = PBXBuildFile; fileRef = 60379E52F4C982E1C790B6519E71C7C7 /* IGListAdapterUpdater.h */; settings = {ATTRIBUTES = (Public, ); }; }; - BC0126520E73770835746D3B1B613938 /* IGListAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = 6ACF94F01EB36325B7E6582A24CE67E1 /* IGListAdapter.m */; }; - BF318B0B45ACAF2725C9AC468D256E3D /* IGListSectionMap.h in Headers */ = {isa = PBXBuildFile; fileRef = D6F285EE404C699C0CC7C31E7245B307 /* IGListSectionMap.h */; settings = {ATTRIBUTES = (Private, ); }; }; - BF4804E0DD82EA483FF3C82F8DFCABBD /* IGListAdapterUpdater.m in Sources */ = {isa = PBXBuildFile; fileRef = 64E8ACC5C6782B94FD1B95596927A543 /* IGListAdapterUpdater.m */; }; - BFEEC2F47FC552E9E6EC80C984A8DE10 /* NSIndexSet+PrettyDescription.h in Headers */ = {isa = PBXBuildFile; fileRef = 5258E047034F850DB89896B38AC9EDB2 /* NSIndexSet+PrettyDescription.h */; settings = {ATTRIBUTES = (Private, ); }; }; - C4328DE47976156C06FB51E1FC1C79FA /* IGListDisplayDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = E2B529498914743C310A5BF137656A18 /* IGListDisplayDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; - C47B57F6C4A0B47A302C95C9FBD5BFDE /* IGListKit-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 85FB0BDA4A7F33F3588C88434ECD2E94 /* IGListKit-dummy.m */; }; - C7B337BF99A703262B38856C2A916613 /* NSObject+IGListDiffable.h in Headers */ = {isa = PBXBuildFile; fileRef = 516F4D39676D39DB68711DFCCF99CD08 /* NSObject+IGListDiffable.h */; settings = {ATTRIBUTES = (Public, ); }; }; - CCCD28F400F07B8C22AC80757491E13B /* IGListAdapterUpdaterInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = D922528E54D29F20913750659CF4DD3E /* IGListAdapterUpdaterInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; - D46249EFD12F9C350961FEA1831DF20F /* IGListBatchUpdateData.h in Headers */ = {isa = PBXBuildFile; fileRef = BE4F9093FE09B54A0DC32E8161904775 /* IGListBatchUpdateData.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DBE42210054F8FDA69270F4EC611FD4C /* IGListScrollDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = A48E8E2621D1D301DF15DC1EA7F25CB7 /* IGListScrollDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; - E01ABFB55E486E56D309DE5BAA801876 /* IGListKit-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 82BBB8E0984E89E3CD3311E21D7F65D6 /* IGListKit-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - EA5AEB7F2DADFF1BA74A38860AA60BA5 /* IGListIndexSetResult.m in Sources */ = {isa = PBXBuildFile; fileRef = B281B0B7972DE5D26848178203A718AE /* IGListIndexSetResult.m */; }; - F360C686D507AA39A221B314C92050B1 /* IGListKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 1DD75371720A47691326032C3842EA7D /* IGListKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F5383C2327F50B07F0904BFE6EB496C8 /* IGListReloadDataUpdater.m in Sources */ = {isa = PBXBuildFile; fileRef = EBFD4BC90748BE8DE367B6DCA73B982A /* IGListReloadDataUpdater.m */; }; - F7023388DF86747C3752D4BCFFD9BE98 /* NSIndexSet+PrettyDescription.m in Sources */ = {isa = PBXBuildFile; fileRef = 380BD8B88A62F76284458B6E06908A47 /* NSIndexSet+PrettyDescription.m */; }; - FD7CE90CC29F48232D88E3273B183752 /* IGListReloadDataUpdater.h in Headers */ = {isa = PBXBuildFile; fileRef = CDA049308F02171E1FE2541EFF16E527 /* IGListReloadDataUpdater.h */; settings = {ATTRIBUTES = (Public, ); }; }; - FF9FF8C3E7C149B40D25B5B2BB530C27 /* Pods-IGListKitExamples-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 52054AE893A0AE7FBFC54333D8ABD345 /* Pods-IGListKitExamples-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 0201DC2443EAB9E8EFD7A4A9A9CFECC5 /* IGListDisplayHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 5863AE1957F0361ED3261719C46C1758 /* IGListDisplayHandler.m */; }; + 02FD4C5495EBB07A03FA84A132A5D45C /* IGListCollectionContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 0D8F0F47DE98C3252F16924EF2CDFE6D /* IGListCollectionContext.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 0614CE98DF942497BF536C8648F93351 /* IGListIndexSetResultInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = D829E3F709882FF702AFED334B671397 /* IGListIndexSetResultInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 064A1A8FFB4ABF19068CA3780789B043 /* IGListIndexPathResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 667B5A2F952792A619FE387BF4329989 /* IGListIndexPathResult.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 08620A926A12C5C18637088543C9F2A6 /* IGListSectionType.h in Headers */ = {isa = PBXBuildFile; fileRef = 01AE564E773788A8781A7D1EC6BE2B8A /* IGListSectionType.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 17C0C840A8B9D1FD50FA407EE419E4D0 /* IGListMoveIndexPath.h in Headers */ = {isa = PBXBuildFile; fileRef = D7085344BDCC7B4DBBB37FA006B80B89 /* IGListMoveIndexPath.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1A4E1A1CB6336FD8D4860F0255A84E19 /* IGListAssert.h in Headers */ = {isa = PBXBuildFile; fileRef = 1DE331AF5EE69F5505389A4B606026B0 /* IGListAssert.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1A89AF7CCCD65D9D5B946363776D05AE /* Pods-IGListKitExamples-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = A8E514E9DA595A3527E8C938A6CAEB1E /* Pods-IGListKitExamples-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1DDAF17BDB3240FFD24E2E8897935122 /* IGListWorkingRangeDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = FE2BA5ED2BAD56B731D54C06AC00B72F /* IGListWorkingRangeDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 22A17D9784C14D8DD5A1EED7AFAF93FA /* IGListAdapterDataSource.h in Headers */ = {isa = PBXBuildFile; fileRef = FD774554CAECD4B6727C7474901F3603 /* IGListAdapterDataSource.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 25CA661803B75AB0476991E21BA42770 /* IGListIndexSetResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 75E3BF27752D3B23EA4375E7628DC77D /* IGListIndexSetResult.m */; }; + 27570C13B6F8420258B5FCC2F6620D4D /* IGListStackedSectionController.h in Headers */ = {isa = PBXBuildFile; fileRef = D84C423B4DFFB471D2F178702762F9AF /* IGListStackedSectionController.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2A829436185BF8282D20F6CFB29065E7 /* IGListExperiments.h in Headers */ = {isa = PBXBuildFile; fileRef = 836082517258A9D41009E52839F7197D /* IGListExperiments.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2C23E0F66B7E1C1F8D37D93A3FFBD4E0 /* IGListIndexPathResultInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 30EF9D6CFFF4FB5D702330BA8ECC4204 /* IGListIndexPathResultInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 2F4DD4F90E39BF5409ABDFBCEF68D5E7 /* IGListCollectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8D7C8296520E9B1E9B23A02237B2B371 /* IGListCollectionView.m */; }; + 3078D3DBACBFD2CC6D2184BF88BCAFAD /* IGListBatchUpdateData.h in Headers */ = {isa = PBXBuildFile; fileRef = 33FDCD6A0E661FF92D0186B8809819D1 /* IGListBatchUpdateData.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 33246AA4C1F98CDBD8C95AA74A8D68BD /* IGListSectionMap.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D53D1FC6E37D144E2123DBA1818E3E3 /* IGListSectionMap.m */; }; + 3B60C19F42DF03B5DC0E9ADB182FABD3 /* IGListDisplayDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 7116C46C152D97F96CE269437340AF86 /* IGListDisplayDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 42D8BD08D4E77F189EA13239DBB03F65 /* IGListWorkingRangeHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 7663F27A733B1D98ABDC7362301054B0 /* IGListWorkingRangeHandler.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 4441ECCCE547C6118B7AD035DF7B28D6 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 616BEB51ECCAD129BDBCB7A956B56CC6 /* Foundation.framework */; }; + 4DC076C43C4AA5A3C88EEC49F5097581 /* Pods-IGListKitMessageExample-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = B2806858B5ED353CF2D8B37BFAE4171C /* Pods-IGListKitMessageExample-dummy.m */; }; + 4FC26BBF235D28B2A5F5B6309FE5936A /* IGListDiffable.h in Headers */ = {isa = PBXBuildFile; fileRef = DF71C4B0ECA6E21DB8448A7B79E9A85A /* IGListDiffable.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 521D101EE7EF9C5A5B7D92BCCEF1A5BB /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 616BEB51ECCAD129BDBCB7A956B56CC6 /* Foundation.framework */; }; + 55FE5865F3D1590ED0019BF6D799BE78 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7EC994CDC2D681BA26389F78A7E4B325 /* UIKit.framework */; }; + 60FBA584D762726D2E2431593C3411E2 /* IGListWorkingRangeHandler.mm in Sources */ = {isa = PBXBuildFile; fileRef = D0545814D0EC0AB3A6C22B35E0BBC030 /* IGListWorkingRangeHandler.mm */; }; + 61766FB6312CF0C8C6CC7B58C163DB82 /* IGListSingleSectionController.h in Headers */ = {isa = PBXBuildFile; fileRef = F3E397AD6485B00E5412DA38E2A259CC /* IGListSingleSectionController.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 63E44C34556274554700CB64E3752300 /* IGListAdapterInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 55B5DC4F227D42720A64141AADBFF882 /* IGListAdapterInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 67EB1BD5E83AAF5CA897879A9A9C2332 /* IGListMoveIndex.m in Sources */ = {isa = PBXBuildFile; fileRef = AE3BC07368663FE65CB4B56914C5BCA7 /* IGListMoveIndex.m */; }; + 72F56377D5CC348C4228A8CB058AF830 /* IGListMoveIndexPathInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C00254DAD873338C1128EE087E9509 /* IGListMoveIndexPathInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 73B8129B5A89D75D7EB7FE0EC324C751 /* IGListDiff.mm in Sources */ = {isa = PBXBuildFile; fileRef = 53C807CB982FACB90000DD53A994C24F /* IGListDiff.mm */; }; + 75000A67FAE5194A808EC2D8D701CC8E /* IGListAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 082E59D92D62734B72D1DDC3A5C15A3F /* IGListAdapter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 79DD3BEC4F26994808F4B708291EA820 /* IGListAdapterUpdater.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C79D692BCABA200CDF96AE4A22B633D /* IGListAdapterUpdater.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7A77DCC596C361613468F117DCFF425F /* IGListSectionMap.h in Headers */ = {isa = PBXBuildFile; fileRef = BB8AFDA3A8F0206266B0BDBD5E89CF98 /* IGListSectionMap.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 7E06046B354A6E26CA1BFC524D7FB48A /* IGListMoveIndexPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E49A47118A1919487DADE4931F92474 /* IGListMoveIndexPath.m */; }; + 81DB1409A04343AA5E7D4387C2806C72 /* IGListAdapterUpdaterDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 4DA6521BF7772A5EA3E951CEE4970AE3 /* IGListAdapterUpdaterDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 8487DEE3683A65AAD6452E22B0533ECB /* IGListKit-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 85FB0BDA4A7F33F3588C88434ECD2E94 /* IGListKit-dummy.m */; }; + 8A3B3A822CBCC5C301403DED2D065DEC /* IGListReloadDataUpdater.h in Headers */ = {isa = PBXBuildFile; fileRef = 2E9009BE5D28B8C45381B6BFE8EFF6D0 /* IGListReloadDataUpdater.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 8A93CB107141878678FCBCE60429C62F /* IGListMoveIndexInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 34DC884E950ED997B02767DB91E4A649 /* IGListMoveIndexInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 8AB84DCBFC8023C35C5AB2138D22C93D /* IGListAdapterUpdater.m in Sources */ = {isa = PBXBuildFile; fileRef = E4682D0326028D1742954DF0ED0ECC51 /* IGListAdapterUpdater.m */; }; + 8F8381656B8CDF4B0B5A3840B7DA160D /* IGListSectionController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1001B9578EF8CD484E47B583D8D7CD84 /* IGListSectionController.m */; }; + 91FE5094076BCD5F00082082E6DE8084 /* IGListIndexSetResult.h in Headers */ = {isa = PBXBuildFile; fileRef = DD0F31C66F1665645FFDF84FCD01944D /* IGListIndexSetResult.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 95981CDF74D7AD863E7F8C3532850839 /* IGListKit-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 82BBB8E0984E89E3CD3311E21D7F65D6 /* IGListKit-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9B4175900859EFF6CEFADD3078B17360 /* UICollectionView+IGListBatchUpdateData.h in Headers */ = {isa = PBXBuildFile; fileRef = A877FF71239D29E797F251F63CECF474 /* UICollectionView+IGListBatchUpdateData.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 9D09BF17D5EDE5292186C5C52230C2D5 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 616BEB51ECCAD129BDBCB7A956B56CC6 /* Foundation.framework */; }; + A6DED991868B6854BEBC3C7250D3A446 /* IGListReloadDataUpdater.m in Sources */ = {isa = PBXBuildFile; fileRef = 35A851CF1D56275EDAD77284662184AB /* IGListReloadDataUpdater.m */; }; + A886AA2548040EDBFFEDEDA310CBDBEA /* IGListStackedSectionControllerInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 614490DFFC9DE71C897192EC892B0C8E /* IGListStackedSectionControllerInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; + ABE4853E18CA830382A2462837E3EBED /* IGListAdapterProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 53D14D75B6152E3245064707D6F3463A /* IGListAdapterProxy.m */; }; + AD51AC5022C8C84A3F23026B0CD036D6 /* NSObject+IGListDiffable.h in Headers */ = {isa = PBXBuildFile; fileRef = E0D42DAFA6A4A19EEA6CD58BA183E9D7 /* NSObject+IGListDiffable.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B1F33CF7BAF6B035172F0AD98CEAFE7F /* IGListScrollDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C48B3D6C37870D8E7DB578128BF04DC /* IGListScrollDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B2B07B2CFD9CB2EC33CCA14854368C00 /* IGListAdapterUpdaterInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 70DF80F4AC05DA10A042C0567209B24C /* IGListAdapterUpdaterInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; + B718064EE1D4B6E9B8212A936CA8EA75 /* Pods-IGListKitTodayExample-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 60C3700A55A1751BE6C71BAEBADD7E7A /* Pods-IGListKitTodayExample-dummy.m */; }; + B737133A4230ACB664806CF20F03FAD1 /* Pods-IGListKitTodayExample-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 3709B01F4A8953783FFACB86C3D0CE15 /* Pods-IGListKitTodayExample-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B843EE9504A7CEC862224D22D34A240E /* IGListDisplayHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = A8E7656B76B2704F7A74EF7C2DCE6F15 /* IGListDisplayHandler.h */; settings = {ATTRIBUTES = (Private, ); }; }; + BCDB1B4A86EADED693F540DF34112AD3 /* IGListAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = C5AEE1C40000E48F6BA5A13134908A3A /* IGListAdapter.m */; }; + C45C182E21F3398B458DB7A9C99DFF45 /* IGListKit.h in Headers */ = {isa = PBXBuildFile; fileRef = FFA6AA44B74879612E1411581AF4DEC7 /* IGListKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C4C4C1B02AFD7277F00A40570658152C /* Pods-IGListKitExamples-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = DE5CE5A84B8F2E7646B7E32B1F54007D /* Pods-IGListKitExamples-dummy.m */; }; + C9549BB7BDAC0EC31EB2804F5FE7BC00 /* IGListSectionControllerInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 567C2BC0CBAC62CA0DBA659D1045942C /* IGListSectionControllerInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; + C98CD17D4DA7CE4D32366790C5438346 /* IGListUpdatingDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = A9F36E8FC50AEADB59AAD67BD7962588 /* IGListUpdatingDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C9B30C305923438D4F5171ED03CEC483 /* IGListCollectionView.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E009D402058A4557F4BD60EDA7621D5 /* IGListCollectionView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + CBB31E3DD44CCE559CD453246280A6FE /* UICollectionView+IGListBatchUpdateData.m in Sources */ = {isa = PBXBuildFile; fileRef = 51E61F5A2DF497DFF8DEBF3C6352976C /* UICollectionView+IGListBatchUpdateData.m */; }; + CDCCA3E3E375EDB3342251690CD052F0 /* IGListMoveIndex.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C247AE0AD292B1B21A1243672E0A1A5 /* IGListMoveIndex.h */; settings = {ATTRIBUTES = (Public, ); }; }; + CF302D5A5C86BC17A36F7368BC2E4F18 /* IGListDiff.h in Headers */ = {isa = PBXBuildFile; fileRef = 9E20BBC002825CE2FD5715F79DE91DD5 /* IGListDiff.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D21C7CE8688679FB2B5159BE89958B22 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 616BEB51ECCAD129BDBCB7A956B56CC6 /* Foundation.framework */; }; + D3FFC74A899A28C284E3CA2E7D834DA3 /* IGListStackedSectionController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6099CEC502FCB187B87F06ED64BBBC1D /* IGListStackedSectionController.m */; }; + DBC4ED99271185BD33163C3C35EECA4C /* IGListAdapterProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 39E0A0CCC6664D0A540F4D46A3EBB557 /* IGListAdapterProxy.h */; settings = {ATTRIBUTES = (Private, ); }; }; + E353B40949D9675B8B2B03C7569F96F5 /* Pods-IGListKitMessageExample-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 5566AE25970A51436D6E32AE60BE5E87 /* Pods-IGListKitMessageExample-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E801D8DCF84428347CFF0F428241B267 /* IGListSectionController.h in Headers */ = {isa = PBXBuildFile; fileRef = 1193C6D51D46D8DDA0BE2FD7E4EE35ED /* IGListSectionController.h */; settings = {ATTRIBUTES = (Public, ); }; }; + ECA097208E20EFF9958E770B85A2777F /* IGListAdapterDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = D23E094B3D67F1B0E6E5B97741F3CA27 /* IGListAdapterDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; + ED78B12343068A5A8CF7D2145C236D7A /* IGListIndexPathResult.m in Sources */ = {isa = PBXBuildFile; fileRef = E5E956D6176274C2D22F6B26C16D307B /* IGListIndexPathResult.m */; }; + F13EBCFFF6329C713E28457CEA2F6818 /* IGListMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = A797E1D5C7D0E09DABA9DB838A2F822B /* IGListMacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F6C6EDF4358AF137CA360ADE80BC8F5D /* IGListSingleSectionController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1C2D642B4A4985AE7BB64C0371E56243 /* IGListSingleSectionController.m */; }; + FA3D8136BFF963A80623A2D9C1613744 /* IGListSupplementaryViewSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 65D85554C94E6AF326DB80AC597949B0 /* IGListSupplementaryViewSource.h */; settings = {ATTRIBUTES = (Public, ); }; }; + FB761405D4AD376F952AA615DF5D1F31 /* NSObject+IGListDiffable.m in Sources */ = {isa = PBXBuildFile; fileRef = F7C4A7A1D6CA44ACF7B060879859C0D3 /* NSObject+IGListDiffable.m */; }; + FC144585E390A54800B24AC3F0540DD8 /* IGListBatchUpdateData.mm in Sources */ = {isa = PBXBuildFile; fileRef = 14F41375D4095CBE1A26CBE60E845E2F /* IGListBatchUpdateData.mm */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 5A4D93DEC315EA1419504908E8F1310B /* PBXContainerItemProxy */ = { + 42B122D03058E7C3E34ACF0AC2A72140 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; proxyType = 1; - remoteGlobalIDString = 26932F09684B706888A7BF05E69D387C; + remoteGlobalIDString = 69D4D7AE264E7E3080B0DF650DDE7F16; + remoteInfo = IGListKit; + }; + 7D332B346FFC0D5E5159546D185DAFEF /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; + proxyType = 1; + remoteGlobalIDString = 69D4D7AE264E7E3080B0DF650DDE7F16; + remoteInfo = IGListKit; + }; + A0A5426482C447F640D6A192E71D5F5B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; + proxyType = 1; + remoteGlobalIDString = 69D4D7AE264E7E3080B0DF650DDE7F16; remoteInfo = IGListKit; }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 0103D32BB7A0A6165DCA97AE90B78FF3 /* IGListWorkingRangeHandler.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; path = IGListWorkingRangeHandler.mm; sourceTree = ""; }; - 0446A9446334650F8C62E86A0E6E53A3 /* IGListDisplayHandler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListDisplayHandler.h; sourceTree = ""; }; - 109159D72077E46327880D41EE69B804 /* IGListAdapterProxy.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListAdapterProxy.h; sourceTree = ""; }; - 17FC1649F3BE2A7A920FF0C7D50B7EC2 /* IGListCollectionContext.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListCollectionContext.h; sourceTree = ""; }; - 1B2B14BA3AB402D9CC387EEB27A2F746 /* Pods-IGListKitExamples.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-IGListKitExamples.debug.xcconfig"; sourceTree = ""; }; - 1DD75371720A47691326032C3842EA7D /* IGListKit.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListKit.h; sourceTree = ""; }; - 1FE4AA45BC45A8EF0F9FB575B19EE801 /* IGListCollectionView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListCollectionView.h; sourceTree = ""; }; - 22F3AD163D43B95418E4F734FDD061F4 /* IGListStackedSectionController.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = IGListStackedSectionController.m; sourceTree = ""; }; - 2F5AE0385534EC7E6CA75003A7280492 /* Pods-IGListKitExamples-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-IGListKitExamples-dummy.m"; sourceTree = ""; }; - 380BD8B88A62F76284458B6E06908A47 /* NSIndexSet+PrettyDescription.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "NSIndexSet+PrettyDescription.m"; sourceTree = ""; }; - 428C13C7C57B2D91F00D94ECF1FA71F8 /* Pods-IGListKitExamples-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-IGListKitExamples-resources.sh"; sourceTree = ""; }; - 4B14381CF1C8B474F904BED10858A3B1 /* IGListDiff.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; path = IGListDiff.mm; sourceTree = ""; }; - 4B5597025F567F3628A6FE6AB07D53F3 /* IGListCollectionView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = IGListCollectionView.m; sourceTree = ""; }; - 4F1AA350148ECB86D3C7EAA99E50E71E /* IGListWorkingRangeHandler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListWorkingRangeHandler.h; sourceTree = ""; }; - 4F331B7F935DA82F2BA8F9EC9CDAC989 /* IGListMoveIndex.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListMoveIndex.h; sourceTree = ""; }; - 4F7D2957E3E38FF3DDE6BDE4FB7B5599 /* UICollectionView+IGListBatchUpdateData.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "UICollectionView+IGListBatchUpdateData.h"; sourceTree = ""; }; - 5074228D8F3A063BF5EE38BBCDC854D8 /* IGListUpdatingDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListUpdatingDelegate.h; sourceTree = ""; }; - 50D66D11EB993B3B287DA0B8DEE153B7 /* IGListSectionController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListSectionController.h; sourceTree = ""; }; - 516F4D39676D39DB68711DFCCF99CD08 /* NSObject+IGListDiffable.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "NSObject+IGListDiffable.h"; sourceTree = ""; }; - 52054AE893A0AE7FBFC54333D8ABD345 /* Pods-IGListKitExamples-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-IGListKitExamples-umbrella.h"; sourceTree = ""; }; - 5258E047034F850DB89896B38AC9EDB2 /* NSIndexSet+PrettyDescription.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "NSIndexSet+PrettyDescription.h"; sourceTree = ""; }; - 5317DB3BAAEE0CC7B2D2B105A879060D /* IGListAssert.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListAssert.h; sourceTree = ""; }; - 54A169D9E10ABA4A657E466A81CF5E96 /* IGListDiffable.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListDiffable.h; sourceTree = ""; }; - 561D1CAC9AE6D43A06CCEAFEC05B04DA /* IGListKit.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = IGListKit.modulemap; sourceTree = ""; }; + 01AE564E773788A8781A7D1EC6BE2B8A /* IGListSectionType.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListSectionType.h; sourceTree = ""; }; + 082E59D92D62734B72D1DDC3A5C15A3F /* IGListAdapter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListAdapter.h; sourceTree = ""; }; + 0C48B3D6C37870D8E7DB578128BF04DC /* IGListScrollDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListScrollDelegate.h; sourceTree = ""; }; + 0D8F0F47DE98C3252F16924EF2CDFE6D /* IGListCollectionContext.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListCollectionContext.h; sourceTree = ""; }; + 0E9E68D2900796EE8622487D6254AC9C /* Pods-IGListKitExamples-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-IGListKitExamples-frameworks.sh"; sourceTree = ""; }; + 1001B9578EF8CD484E47B583D8D7CD84 /* IGListSectionController.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = IGListSectionController.m; sourceTree = ""; }; + 116948205344E279070B2977E925F803 /* IGListKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = IGListKit.framework; path = IGListKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 1193C6D51D46D8DDA0BE2FD7E4EE35ED /* IGListSectionController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListSectionController.h; sourceTree = ""; }; + 14F41375D4095CBE1A26CBE60E845E2F /* IGListBatchUpdateData.mm */ = {isa = PBXFileReference; includeInIndex = 1; path = IGListBatchUpdateData.mm; sourceTree = ""; }; + 1B2E0BC65B098972E1E94F970F834DA0 /* Pods-IGListKitTodayExample.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; path = "Pods-IGListKitTodayExample.modulemap"; sourceTree = ""; }; + 1C247AE0AD292B1B21A1243672E0A1A5 /* IGListMoveIndex.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListMoveIndex.h; sourceTree = ""; }; + 1C2D642B4A4985AE7BB64C0371E56243 /* IGListSingleSectionController.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = IGListSingleSectionController.m; sourceTree = ""; }; + 1DE331AF5EE69F5505389A4B606026B0 /* IGListAssert.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListAssert.h; sourceTree = ""; }; + 20D642EAE3662BDC17956017E6D622E8 /* Pods-IGListKitMessageExample-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-IGListKitMessageExample-acknowledgements.markdown"; sourceTree = ""; }; + 2698205F5C5CB69B82E6AC7C1D7E9519 /* Pods-IGListKitExamples-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-IGListKitExamples-resources.sh"; sourceTree = ""; }; + 270C1C7FCBA7F319FD7A0398BC18710F /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 2E9009BE5D28B8C45381B6BFE8EFF6D0 /* IGListReloadDataUpdater.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListReloadDataUpdater.h; sourceTree = ""; }; + 30EF9D6CFFF4FB5D702330BA8ECC4204 /* IGListIndexPathResultInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListIndexPathResultInternal.h; sourceTree = ""; }; + 33FDCD6A0E661FF92D0186B8809819D1 /* IGListBatchUpdateData.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListBatchUpdateData.h; sourceTree = ""; }; + 34DC884E950ED997B02767DB91E4A649 /* IGListMoveIndexInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListMoveIndexInternal.h; sourceTree = ""; }; + 3546419AAFB29CE358FDE5691F031F9E /* Pods_IGListKitTodayExample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_IGListKitTodayExample.framework; path = "Pods-IGListKitTodayExample.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; + 35A851CF1D56275EDAD77284662184AB /* IGListReloadDataUpdater.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = IGListReloadDataUpdater.m; sourceTree = ""; }; + 3709B01F4A8953783FFACB86C3D0CE15 /* Pods-IGListKitTodayExample-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-IGListKitTodayExample-umbrella.h"; sourceTree = ""; }; + 39E0A0CCC6664D0A540F4D46A3EBB557 /* IGListAdapterProxy.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListAdapterProxy.h; sourceTree = ""; }; + 3DFBEA9D0D85DB9366D3C949C20332DD /* Pods_IGListKitExamples.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_IGListKitExamples.framework; path = "Pods-IGListKitExamples.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; + 47B8147DC6434174D9E3054DA3CB4484 /* Pods-IGListKitMessageExample.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; path = "Pods-IGListKitMessageExample.modulemap"; sourceTree = ""; }; + 4DA6521BF7772A5EA3E951CEE4970AE3 /* IGListAdapterUpdaterDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListAdapterUpdaterDelegate.h; sourceTree = ""; }; + 4F9A8086AF09CCA586431BFEE5DE2CA3 /* Pods-IGListKitMessageExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-IGListKitMessageExample.debug.xcconfig"; sourceTree = ""; }; + 51E61F5A2DF497DFF8DEBF3C6352976C /* UICollectionView+IGListBatchUpdateData.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "UICollectionView+IGListBatchUpdateData.m"; sourceTree = ""; }; + 53C807CB982FACB90000DD53A994C24F /* IGListDiff.mm */ = {isa = PBXFileReference; includeInIndex = 1; path = IGListDiff.mm; sourceTree = ""; }; + 53D14D75B6152E3245064707D6F3463A /* IGListAdapterProxy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = IGListAdapterProxy.m; sourceTree = ""; }; + 5566AE25970A51436D6E32AE60BE5E87 /* Pods-IGListKitMessageExample-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-IGListKitMessageExample-umbrella.h"; sourceTree = ""; }; + 55B5DC4F227D42720A64141AADBFF882 /* IGListAdapterInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListAdapterInternal.h; sourceTree = ""; }; + 561D1CAC9AE6D43A06CCEAFEC05B04DA /* IGListKit.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; path = IGListKit.modulemap; sourceTree = ""; }; + 567C2BC0CBAC62CA0DBA659D1045942C /* IGListSectionControllerInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListSectionControllerInternal.h; sourceTree = ""; }; + 568FA20FCC9D77DF4FF3A77159CB66AA /* Pods-IGListKitExamples.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-IGListKitExamples.release.xcconfig"; sourceTree = ""; }; + 57D6B0172E92F207DDCC38AA57BBD76C /* Pods_IGListKitMessageExample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_IGListKitMessageExample.framework; path = "Pods-IGListKitMessageExample.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; + 5863AE1957F0361ED3261719C46C1758 /* IGListDisplayHandler.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = IGListDisplayHandler.m; sourceTree = ""; }; 5B065D6991AF097908DF9824689FB9C4 /* IGListKit-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "IGListKit-prefix.pch"; sourceTree = ""; }; - 60379E52F4C982E1C790B6519E71C7C7 /* IGListAdapterUpdater.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListAdapterUpdater.h; sourceTree = ""; }; - 64E8ACC5C6782B94FD1B95596927A543 /* IGListAdapterUpdater.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = IGListAdapterUpdater.m; sourceTree = ""; }; - 6ACF94F01EB36325B7E6582A24CE67E1 /* IGListAdapter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = IGListAdapter.m; sourceTree = ""; }; - 6E2D3628C46D46E7D75C2D9C65C0C6E7 /* IGListAdapterProxy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = IGListAdapterProxy.m; sourceTree = ""; }; - 720FAF43FD40FA27160DB53AD4C8E73D /* NSObject+IGListDiffable.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "NSObject+IGListDiffable.m"; sourceTree = ""; }; - 73259AA7FEA14577AEF2DB550C3020EB /* IGListAdapter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListAdapter.h; sourceTree = ""; }; - 7377305092E6A1E16624C7EBA4782FED /* IGListIndexPathResultInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListIndexPathResultInternal.h; sourceTree = ""; }; - 7ADB9063D305B8288C4BB24BC56A463F /* IGListMoveIndexInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListMoveIndexInternal.h; sourceTree = ""; }; - 7E7FEF0C49C387ED472744AB5E63D5C5 /* IGListMacros.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListMacros.h; sourceTree = ""; }; - 7F401C4ED6FD8A5953382E94BFDC1B04 /* IGListMoveIndexPath.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = IGListMoveIndexPath.m; sourceTree = ""; }; + 5EC090A99FE4CA3786E651AF9C907913 /* Pods-IGListKitTodayExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-IGListKitTodayExample.debug.xcconfig"; sourceTree = ""; }; + 6099CEC502FCB187B87F06ED64BBBC1D /* IGListStackedSectionController.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = IGListStackedSectionController.m; sourceTree = ""; }; + 60C3700A55A1751BE6C71BAEBADD7E7A /* Pods-IGListKitTodayExample-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-IGListKitTodayExample-dummy.m"; sourceTree = ""; }; + 614490DFFC9DE71C897192EC892B0C8E /* IGListStackedSectionControllerInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListStackedSectionControllerInternal.h; sourceTree = ""; }; + 616BEB51ECCAD129BDBCB7A956B56CC6 /* 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; }; + 65A1389E308E5581D73D099A74A15628 /* Pods-IGListKitMessageExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-IGListKitMessageExample.release.xcconfig"; sourceTree = ""; }; + 65D85554C94E6AF326DB80AC597949B0 /* IGListSupplementaryViewSource.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListSupplementaryViewSource.h; sourceTree = ""; }; + 667B5A2F952792A619FE387BF4329989 /* IGListIndexPathResult.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListIndexPathResult.h; sourceTree = ""; }; + 6D53D1FC6E37D144E2123DBA1818E3E3 /* IGListSectionMap.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = IGListSectionMap.m; sourceTree = ""; }; + 6E49A47118A1919487DADE4931F92474 /* IGListMoveIndexPath.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = IGListMoveIndexPath.m; sourceTree = ""; }; + 70DF80F4AC05DA10A042C0567209B24C /* IGListAdapterUpdaterInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListAdapterUpdaterInternal.h; sourceTree = ""; }; + 7116C46C152D97F96CE269437340AF86 /* IGListDisplayDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListDisplayDelegate.h; sourceTree = ""; }; + 7200C49C89FA68816227219403B87DBE /* Pods-IGListKitMessageExample-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-IGListKitMessageExample-acknowledgements.plist"; sourceTree = ""; }; + 75E3BF27752D3B23EA4375E7628DC77D /* IGListIndexSetResult.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = IGListIndexSetResult.m; sourceTree = ""; }; + 7663F27A733B1D98ABDC7362301054B0 /* IGListWorkingRangeHandler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListWorkingRangeHandler.h; sourceTree = ""; }; + 7ACA5B41E2D11D0ECE0F0A2D8B3370D5 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 7E009D402058A4557F4BD60EDA7621D5 /* IGListCollectionView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListCollectionView.h; sourceTree = ""; }; + 7EC994CDC2D681BA26389F78A7E4B325 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.0.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; 82BBB8E0984E89E3CD3311E21D7F65D6 /* IGListKit-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "IGListKit-umbrella.h"; sourceTree = ""; }; - 84752D2DDFC17301AD69B035A1ABEB98 /* IGListIndexSetResult.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListIndexSetResult.h; sourceTree = ""; }; + 836082517258A9D41009E52839F7197D /* IGListExperiments.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListExperiments.h; sourceTree = ""; }; 85FB0BDA4A7F33F3588C88434ECD2E94 /* IGListKit-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "IGListKit-dummy.m"; sourceTree = ""; }; + 86C00254DAD873338C1128EE087E9509 /* IGListMoveIndexPathInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListMoveIndexPathInternal.h; sourceTree = ""; }; 891CE36E66A66905E25AD89B001B5648 /* IGListKit.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = IGListKit.xcconfig; sourceTree = ""; }; - 8C9AC4FA89437FC74B5044CB6E09F330 /* IGListAdapterDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListAdapterDelegate.h; sourceTree = ""; }; - 8CFC4E4785DC5CD494D3BA69EE0EF1C5 /* IGListExperiments.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListExperiments.h; sourceTree = ""; }; - 8D8C265CA74986A39B9EF8127AE0349D /* IGListMoveIndexPathInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListMoveIndexPathInternal.h; sourceTree = ""; }; - 91007FC1F36EE50D4609909509B4BE04 /* IGListSingleSectionController.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = IGListSingleSectionController.m; sourceTree = ""; }; - 923F1BE703C78DB09D0F325460A4A2EA /* IGListAdapterUpdaterDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListAdapterUpdaterDelegate.h; sourceTree = ""; }; - 928F8C884AA9FD0FBF674F4CF5DAC4D8 /* IGListSectionControllerInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListSectionControllerInternal.h; sourceTree = ""; }; - 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; - 9D11DCAE06F644E6CCE659622CD8E616 /* IGListKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = IGListKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 9E99717CDC2053D36C6789D1148FB800 /* UICollectionView+IGListBatchUpdateData.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "UICollectionView+IGListBatchUpdateData.m"; sourceTree = ""; }; - A198E265B2C6E673C7C9C5050F92D9F0 /* Pods-IGListKitExamples.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-IGListKitExamples.release.xcconfig"; sourceTree = ""; }; - A25B427B6865597BD60B14637B4DF317 /* IGListMoveIndexPath.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListMoveIndexPath.h; sourceTree = ""; }; - A2A6FF208CEC4C2861F1E9D42D651453 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.3.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; - A48E8E2621D1D301DF15DC1EA7F25CB7 /* IGListScrollDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListScrollDelegate.h; sourceTree = ""; }; - A6A48D5B55D7631327C124F538C6E068 /* IGListSingleSectionController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListSingleSectionController.h; sourceTree = ""; }; - A7BBE69D34859663403DA26F14CC4DDB /* Pods-IGListKitExamples-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-IGListKitExamples-acknowledgements.markdown"; sourceTree = ""; }; - A851A4ACB8C0DE98BFFBC6FD4D1BACEE /* Pods-IGListKitExamples-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-IGListKitExamples-frameworks.sh"; sourceTree = ""; }; - ABF549428FEA18696E5358F599E11A24 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - B281B0B7972DE5D26848178203A718AE /* IGListIndexSetResult.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = IGListIndexSetResult.m; sourceTree = ""; }; - B3A4D0DCC742ED05F9B0EAD98B483829 /* IGListDiff.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListDiff.h; sourceTree = ""; }; - B4D067AEE0F5C07151A19715FCE108F3 /* IGListIndexSetResultInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListIndexSetResultInternal.h; sourceTree = ""; }; - B9B2C760A6B8BC4E2F9B9BC221585A06 /* IGListStackedSectionController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListStackedSectionController.h; sourceTree = ""; }; - BA166501E81C4BA1DF5A400979E86CDB /* IGListSectionMap.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = IGListSectionMap.m; sourceTree = ""; }; - BE4F9093FE09B54A0DC32E8161904775 /* IGListBatchUpdateData.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListBatchUpdateData.h; sourceTree = ""; }; + 8D7C8296520E9B1E9B23A02237B2B371 /* IGListCollectionView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = IGListCollectionView.m; sourceTree = ""; }; + 922574DF06D0AD5E3964986609327D1F /* Pods-IGListKitTodayExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-IGListKitTodayExample.release.xcconfig"; sourceTree = ""; }; + 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + 9507E646FDB2D9764FC70560DD8DBEF2 /* Pods-IGListKitTodayExample-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-IGListKitTodayExample-acknowledgements.markdown"; sourceTree = ""; }; + 9C79D692BCABA200CDF96AE4A22B633D /* IGListAdapterUpdater.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListAdapterUpdater.h; sourceTree = ""; }; + 9E20BBC002825CE2FD5715F79DE91DD5 /* IGListDiff.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListDiff.h; sourceTree = ""; }; + A72EA0FFEA9D25CBF9BD8F7F2CE9F2FE /* Pods-IGListKitExamples-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-IGListKitExamples-acknowledgements.plist"; sourceTree = ""; }; + A797E1D5C7D0E09DABA9DB838A2F822B /* IGListMacros.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListMacros.h; sourceTree = ""; }; + A877FF71239D29E797F251F63CECF474 /* UICollectionView+IGListBatchUpdateData.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "UICollectionView+IGListBatchUpdateData.h"; sourceTree = ""; }; + A8E514E9DA595A3527E8C938A6CAEB1E /* Pods-IGListKitExamples-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-IGListKitExamples-umbrella.h"; sourceTree = ""; }; + A8E7656B76B2704F7A74EF7C2DCE6F15 /* IGListDisplayHandler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListDisplayHandler.h; sourceTree = ""; }; + A9F36E8FC50AEADB59AAD67BD7962588 /* IGListUpdatingDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListUpdatingDelegate.h; sourceTree = ""; }; + AE3BC07368663FE65CB4B56914C5BCA7 /* IGListMoveIndex.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = IGListMoveIndex.m; sourceTree = ""; }; + B2806858B5ED353CF2D8B37BFAE4171C /* Pods-IGListKitMessageExample-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-IGListKitMessageExample-dummy.m"; sourceTree = ""; }; + B66E6B5AEB9406EAEFA9710E6E9962F2 /* Pods-IGListKitMessageExample-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-IGListKitMessageExample-resources.sh"; sourceTree = ""; }; + BB8AFDA3A8F0206266B0BDBD5E89CF98 /* IGListSectionMap.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListSectionMap.h; sourceTree = ""; }; + BC1C46146C230C9011237AAC07BFBD9C /* Pods-IGListKitExamples.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; path = "Pods-IGListKitExamples.modulemap"; sourceTree = ""; }; BF8DCC2E99230AF598F30C8A54C525FB /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - C0D34FDB422AF09AA6F7813D34DA3DCD /* IGListSectionType.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListSectionType.h; sourceTree = ""; }; - C7F454644FEBF5DB647AE1728D1FD067 /* Pods_IGListKitExamples.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_IGListKitExamples.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - CDA049308F02171E1FE2541EFF16E527 /* IGListReloadDataUpdater.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListReloadDataUpdater.h; sourceTree = ""; }; - D0AEE94B91F9849EEF961CC1C265C985 /* IGListBatchUpdateData.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; path = IGListBatchUpdateData.mm; sourceTree = ""; }; - D37ACDCF54F63073142D7196E56946A3 /* IGListMoveIndex.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = IGListMoveIndex.m; sourceTree = ""; }; - D3934C6500E5C7C907F1AC3B6C1AF15C /* IGListDisplayHandler.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = IGListDisplayHandler.m; sourceTree = ""; }; - D6F285EE404C699C0CC7C31E7245B307 /* IGListSectionMap.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListSectionMap.h; sourceTree = ""; }; - D7D841899F69CAEFE9CC75F4C742EB7F /* IGListSupplementaryViewSource.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListSupplementaryViewSource.h; sourceTree = ""; }; - D803D538BF4074498E5ADB84A16E0395 /* Pods-IGListKitExamples-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-IGListKitExamples-acknowledgements.plist"; sourceTree = ""; }; - D922528E54D29F20913750659CF4DD3E /* IGListAdapterUpdaterInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListAdapterUpdaterInternal.h; sourceTree = ""; }; - D9F947E7710011A32E4FA3C988472760 /* IGListWorkingRangeDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListWorkingRangeDelegate.h; sourceTree = ""; }; - DBA04B01FE70BC1FC9B2AF5A04816653 /* IGListIndexPathResult.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListIndexPathResult.h; sourceTree = ""; }; - DC277CBFF0D26310BEA0C5603C4EAA45 /* IGListAdapterInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListAdapterInternal.h; sourceTree = ""; }; - DD1EB6F6A5F5CF2DA79688B3A01F95BC /* IGListIndexPathResult.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = IGListIndexPathResult.m; sourceTree = ""; }; - DD4F28A7CC1A638EF87DA9D5583C4CAA /* IGListStackedSectionControllerInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListStackedSectionControllerInternal.h; sourceTree = ""; }; - DDF922EBFB237C1B42E8B07306D987E8 /* Pods-IGListKitExamples.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = "Pods-IGListKitExamples.modulemap"; sourceTree = ""; }; - E2B529498914743C310A5BF137656A18 /* IGListDisplayDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListDisplayDelegate.h; sourceTree = ""; }; - E86668F20F252C440D1015B816BE59C5 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.3.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; - EBFD4BC90748BE8DE367B6DCA73B982A /* IGListReloadDataUpdater.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = IGListReloadDataUpdater.m; sourceTree = ""; }; - F5AD8343AC8B755A3258D6E45FFD2D8A /* IGListSectionController.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = IGListSectionController.m; sourceTree = ""; }; - FE4F9D5E24C8E166CBE1324FB4EFE901 /* IGListAdapterDataSource.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListAdapterDataSource.h; sourceTree = ""; }; + C5AEE1C40000E48F6BA5A13134908A3A /* IGListAdapter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = IGListAdapter.m; sourceTree = ""; }; + C6A8BD108D2490E4BA19FA93AD18A83C /* Pods-IGListKitTodayExample-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-IGListKitTodayExample-acknowledgements.plist"; sourceTree = ""; }; + CDDAB8A20B8596ACE7CC916120EE2489 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + D0545814D0EC0AB3A6C22B35E0BBC030 /* IGListWorkingRangeHandler.mm */ = {isa = PBXFileReference; includeInIndex = 1; path = IGListWorkingRangeHandler.mm; sourceTree = ""; }; + D23E094B3D67F1B0E6E5B97741F3CA27 /* IGListAdapterDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListAdapterDelegate.h; sourceTree = ""; }; + D7085344BDCC7B4DBBB37FA006B80B89 /* IGListMoveIndexPath.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListMoveIndexPath.h; sourceTree = ""; }; + D829E3F709882FF702AFED334B671397 /* IGListIndexSetResultInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListIndexSetResultInternal.h; sourceTree = ""; }; + D84C423B4DFFB471D2F178702762F9AF /* IGListStackedSectionController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListStackedSectionController.h; sourceTree = ""; }; + DD0F31C66F1665645FFDF84FCD01944D /* IGListIndexSetResult.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListIndexSetResult.h; sourceTree = ""; }; + DE5CE5A84B8F2E7646B7E32B1F54007D /* Pods-IGListKitExamples-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-IGListKitExamples-dummy.m"; sourceTree = ""; }; + DF71C4B0ECA6E21DB8448A7B79E9A85A /* IGListDiffable.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListDiffable.h; sourceTree = ""; }; + E0D42DAFA6A4A19EEA6CD58BA183E9D7 /* NSObject+IGListDiffable.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "NSObject+IGListDiffable.h"; sourceTree = ""; }; + E1915F3ED5785508E2E252B0D5CD0AB9 /* Pods-IGListKitExamples.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-IGListKitExamples.debug.xcconfig"; sourceTree = ""; }; + E4682D0326028D1742954DF0ED0ECC51 /* IGListAdapterUpdater.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = IGListAdapterUpdater.m; sourceTree = ""; }; + E5E956D6176274C2D22F6B26C16D307B /* IGListIndexPathResult.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = IGListIndexPathResult.m; sourceTree = ""; }; + EC95D5B65CC92046D33001EC1BE7B9A3 /* Pods-IGListKitExamples-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-IGListKitExamples-acknowledgements.markdown"; sourceTree = ""; }; + EF77CF1069D312C499D2898F20FB8DC1 /* Pods-IGListKitTodayExample-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-IGListKitTodayExample-resources.sh"; sourceTree = ""; }; + F3E397AD6485B00E5412DA38E2A259CC /* IGListSingleSectionController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListSingleSectionController.h; sourceTree = ""; }; + F7C4A7A1D6CA44ACF7B060879859C0D3 /* NSObject+IGListDiffable.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "NSObject+IGListDiffable.m"; sourceTree = ""; }; + FD774554CAECD4B6727C7474901F3603 /* IGListAdapterDataSource.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListAdapterDataSource.h; sourceTree = ""; }; + FE2BA5ED2BAD56B731D54C06AC00B72F /* IGListWorkingRangeDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListWorkingRangeDelegate.h; sourceTree = ""; }; + FFA6AA44B74879612E1411581AF4DEC7 /* IGListKit.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = IGListKit.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - AA75830E6081F3DABCD8A9D38D8D20E7 /* Frameworks */ = { + 4A5EAB00BE8AF762691C11C9B294D9A3 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9D09BF17D5EDE5292186C5C52230C2D5 /* Foundation.framework in Frameworks */, + 55FE5865F3D1590ED0019BF6D799BE78 /* UIKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B2FDE9ED50A78E4384C3AB5BADC034B3 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4441ECCCE547C6118B7AD035DF7B28D6 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D7057175063065567057895AB005C590 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 28063C0E5F9119F809C37919575A132F /* Foundation.framework in Frameworks */, + D21C7CE8688679FB2B5159BE89958B22 /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - FE924FF264CD5BDB6DFE9C2ACA63FCAC /* Frameworks */ = { + E9A8D02E745CDFBE4784E186849B8E0E /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 419BBEB1F205EA82FF1A300B6E954F7D /* Foundation.framework in Frameworks */, - 4CCFD8A322D6F78F55604A0E638FE191 /* UIKit.framework in Frameworks */, + 521D101EE7EF9C5A5B7D92BCCEF1A5BB /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -200,13 +252,31 @@ 0461D34BBFD8CE6835409D3733A89161 /* IGListKit */ = { isa = PBXGroup; children = ( - F140F35915E040972E6D461E635BCD4C /* Source */, + A8935A847EEAAE244248CCE166BAA569 /* Source */, DAB5B0D31F1F31F2EA5708FF996EE588 /* Support Files */, ); name = IGListKit; path = ../..; sourceTree = ""; }; + 1EBDBB4238A68D79AF367FABE2670D55 /* Pods-IGListKitExamples */ = { + isa = PBXGroup; + children = ( + CDDAB8A20B8596ACE7CC916120EE2489 /* Info.plist */, + BC1C46146C230C9011237AAC07BFBD9C /* Pods-IGListKitExamples.modulemap */, + EC95D5B65CC92046D33001EC1BE7B9A3 /* Pods-IGListKitExamples-acknowledgements.markdown */, + A72EA0FFEA9D25CBF9BD8F7F2CE9F2FE /* Pods-IGListKitExamples-acknowledgements.plist */, + DE5CE5A84B8F2E7646B7E32B1F54007D /* Pods-IGListKitExamples-dummy.m */, + 0E9E68D2900796EE8622487D6254AC9C /* Pods-IGListKitExamples-frameworks.sh */, + 2698205F5C5CB69B82E6AC7C1D7E9519 /* Pods-IGListKitExamples-resources.sh */, + A8E514E9DA595A3527E8C938A6CAEB1E /* Pods-IGListKitExamples-umbrella.h */, + E1915F3ED5785508E2E252B0D5CD0AB9 /* Pods-IGListKitExamples.debug.xcconfig */, + 568FA20FCC9D77DF4FF3A77159CB66AA /* Pods-IGListKitExamples.release.xcconfig */, + ); + name = "Pods-IGListKitExamples"; + path = "Target Support Files/Pods-IGListKitExamples"; + sourceTree = ""; + }; 275D18F543186A905E745D345F66E093 /* Development Pods */ = { isa = PBXGroup; children = ( @@ -215,56 +285,65 @@ name = "Development Pods"; sourceTree = ""; }; - 433CD3331B6C3787F473C941B61FC68F /* Frameworks */ = { + 2816B4C23FC52ADE9F73C37F72652FD0 /* Targets Support Files */ = { isa = PBXGroup; children = ( - F302CD3B306AF1ED96B9AF31FCDBC26C /* iOS */, + 1EBDBB4238A68D79AF367FABE2670D55 /* Pods-IGListKitExamples */, + 8F7A3DF8D470AB3D415AAA6D8CCC3498 /* Pods-IGListKitMessageExample */, + 3EE9680535CB73BCFDE6DD41E95799B5 /* Pods-IGListKitTodayExample */, ); - name = Frameworks; + name = "Targets Support Files"; sourceTree = ""; }; - 51A62FAD141FCC64FABDAA958233E728 /* Targets Support Files */ = { + 36EFBC6A23BC1F7AE38FF774C39826A1 /* Internal */ = { isa = PBXGroup; children = ( - F22E6673D29C1778B1984CF7D4D871E9 /* Pods-IGListKitExamples */, + 55B5DC4F227D42720A64141AADBFF882 /* IGListAdapterInternal.h */, + 39E0A0CCC6664D0A540F4D46A3EBB557 /* IGListAdapterProxy.h */, + 53D14D75B6152E3245064707D6F3463A /* IGListAdapterProxy.m */, + 70DF80F4AC05DA10A042C0567209B24C /* IGListAdapterUpdaterInternal.h */, + A8E7656B76B2704F7A74EF7C2DCE6F15 /* IGListDisplayHandler.h */, + 5863AE1957F0361ED3261719C46C1758 /* IGListDisplayHandler.m */, + 30EF9D6CFFF4FB5D702330BA8ECC4204 /* IGListIndexPathResultInternal.h */, + D829E3F709882FF702AFED334B671397 /* IGListIndexSetResultInternal.h */, + 34DC884E950ED997B02767DB91E4A649 /* IGListMoveIndexInternal.h */, + 86C00254DAD873338C1128EE087E9509 /* IGListMoveIndexPathInternal.h */, + 567C2BC0CBAC62CA0DBA659D1045942C /* IGListSectionControllerInternal.h */, + BB8AFDA3A8F0206266B0BDBD5E89CF98 /* IGListSectionMap.h */, + 6D53D1FC6E37D144E2123DBA1818E3E3 /* IGListSectionMap.m */, + 614490DFFC9DE71C897192EC892B0C8E /* IGListStackedSectionControllerInternal.h */, + 7663F27A733B1D98ABDC7362301054B0 /* IGListWorkingRangeHandler.h */, + D0545814D0EC0AB3A6C22B35E0BBC030 /* IGListWorkingRangeHandler.mm */, + A877FF71239D29E797F251F63CECF474 /* UICollectionView+IGListBatchUpdateData.h */, + 51E61F5A2DF497DFF8DEBF3C6352976C /* UICollectionView+IGListBatchUpdateData.m */, ); - name = "Targets Support Files"; + name = Internal; + path = Internal; sourceTree = ""; }; - 568515C4F4B02B048840EBD06A1CC65D /* Internal */ = { + 3EE9680535CB73BCFDE6DD41E95799B5 /* Pods-IGListKitTodayExample */ = { isa = PBXGroup; children = ( - DC277CBFF0D26310BEA0C5603C4EAA45 /* IGListAdapterInternal.h */, - 109159D72077E46327880D41EE69B804 /* IGListAdapterProxy.h */, - 6E2D3628C46D46E7D75C2D9C65C0C6E7 /* IGListAdapterProxy.m */, - D922528E54D29F20913750659CF4DD3E /* IGListAdapterUpdaterInternal.h */, - 0446A9446334650F8C62E86A0E6E53A3 /* IGListDisplayHandler.h */, - D3934C6500E5C7C907F1AC3B6C1AF15C /* IGListDisplayHandler.m */, - 7377305092E6A1E16624C7EBA4782FED /* IGListIndexPathResultInternal.h */, - B4D067AEE0F5C07151A19715FCE108F3 /* IGListIndexSetResultInternal.h */, - 7ADB9063D305B8288C4BB24BC56A463F /* IGListMoveIndexInternal.h */, - 8D8C265CA74986A39B9EF8127AE0349D /* IGListMoveIndexPathInternal.h */, - 928F8C884AA9FD0FBF674F4CF5DAC4D8 /* IGListSectionControllerInternal.h */, - D6F285EE404C699C0CC7C31E7245B307 /* IGListSectionMap.h */, - BA166501E81C4BA1DF5A400979E86CDB /* IGListSectionMap.m */, - DD4F28A7CC1A638EF87DA9D5583C4CAA /* IGListStackedSectionControllerInternal.h */, - 4F1AA350148ECB86D3C7EAA99E50E71E /* IGListWorkingRangeHandler.h */, - 0103D32BB7A0A6165DCA97AE90B78FF3 /* IGListWorkingRangeHandler.mm */, - 5258E047034F850DB89896B38AC9EDB2 /* NSIndexSet+PrettyDescription.h */, - 380BD8B88A62F76284458B6E06908A47 /* NSIndexSet+PrettyDescription.m */, - 4F7D2957E3E38FF3DDE6BDE4FB7B5599 /* UICollectionView+IGListBatchUpdateData.h */, - 9E99717CDC2053D36C6789D1148FB800 /* UICollectionView+IGListBatchUpdateData.m */, + 7ACA5B41E2D11D0ECE0F0A2D8B3370D5 /* Info.plist */, + 1B2E0BC65B098972E1E94F970F834DA0 /* Pods-IGListKitTodayExample.modulemap */, + 9507E646FDB2D9764FC70560DD8DBEF2 /* Pods-IGListKitTodayExample-acknowledgements.markdown */, + C6A8BD108D2490E4BA19FA93AD18A83C /* Pods-IGListKitTodayExample-acknowledgements.plist */, + 60C3700A55A1751BE6C71BAEBADD7E7A /* Pods-IGListKitTodayExample-dummy.m */, + EF77CF1069D312C499D2898F20FB8DC1 /* Pods-IGListKitTodayExample-resources.sh */, + 3709B01F4A8953783FFACB86C3D0CE15 /* Pods-IGListKitTodayExample-umbrella.h */, + 5EC090A99FE4CA3786E651AF9C907913 /* Pods-IGListKitTodayExample.debug.xcconfig */, + 922574DF06D0AD5E3964986609327D1F /* Pods-IGListKitTodayExample.release.xcconfig */, ); - path = Internal; + name = "Pods-IGListKitTodayExample"; + path = "Target Support Files/Pods-IGListKitTodayExample"; sourceTree = ""; }; - 61F96534B3AFE724944526CC9F6F2EFE /* Products */ = { + 433CD3331B6C3787F473C941B61FC68F /* Frameworks */ = { isa = PBXGroup; children = ( - 9D11DCAE06F644E6CCE659622CD8E616 /* IGListKit.framework */, - C7F454644FEBF5DB647AE1728D1FD067 /* Pods_IGListKitExamples.framework */, + E6EE98446B568159EE277B68FD442AF0 /* iOS */, ); - name = Products; + name = Frameworks; sourceTree = ""; }; 7DB346D0F39D3F0E887471402A8071AB = { @@ -273,99 +352,110 @@ 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */, 275D18F543186A905E745D345F66E093 /* Development Pods */, 433CD3331B6C3787F473C941B61FC68F /* Frameworks */, - 61F96534B3AFE724944526CC9F6F2EFE /* Products */, - 51A62FAD141FCC64FABDAA958233E728 /* Targets Support Files */, + CF9909136132DE20E8D2AD0C67AA0C49 /* Products */, + 2816B4C23FC52ADE9F73C37F72652FD0 /* Targets Support Files */, ); sourceTree = ""; }; - DAB5B0D31F1F31F2EA5708FF996EE588 /* Support Files */ = { + 8F7A3DF8D470AB3D415AAA6D8CCC3498 /* Pods-IGListKitMessageExample */ = { isa = PBXGroup; children = ( - 561D1CAC9AE6D43A06CCEAFEC05B04DA /* IGListKit.modulemap */, - 891CE36E66A66905E25AD89B001B5648 /* IGListKit.xcconfig */, - 85FB0BDA4A7F33F3588C88434ECD2E94 /* IGListKit-dummy.m */, - 5B065D6991AF097908DF9824689FB9C4 /* IGListKit-prefix.pch */, - 82BBB8E0984E89E3CD3311E21D7F65D6 /* IGListKit-umbrella.h */, - BF8DCC2E99230AF598F30C8A54C525FB /* Info.plist */, + 270C1C7FCBA7F319FD7A0398BC18710F /* Info.plist */, + 47B8147DC6434174D9E3054DA3CB4484 /* Pods-IGListKitMessageExample.modulemap */, + 20D642EAE3662BDC17956017E6D622E8 /* Pods-IGListKitMessageExample-acknowledgements.markdown */, + 7200C49C89FA68816227219403B87DBE /* Pods-IGListKitMessageExample-acknowledgements.plist */, + B2806858B5ED353CF2D8B37BFAE4171C /* Pods-IGListKitMessageExample-dummy.m */, + B66E6B5AEB9406EAEFA9710E6E9962F2 /* Pods-IGListKitMessageExample-resources.sh */, + 5566AE25970A51436D6E32AE60BE5E87 /* Pods-IGListKitMessageExample-umbrella.h */, + 4F9A8086AF09CCA586431BFEE5DE2CA3 /* Pods-IGListKitMessageExample.debug.xcconfig */, + 65A1389E308E5581D73D099A74A15628 /* Pods-IGListKitMessageExample.release.xcconfig */, ); - name = "Support Files"; - path = "Example/Pods/Target Support Files/IGListKit"; + name = "Pods-IGListKitMessageExample"; + path = "Target Support Files/Pods-IGListKitMessageExample"; sourceTree = ""; }; - F140F35915E040972E6D461E635BCD4C /* Source */ = { + A8935A847EEAAE244248CCE166BAA569 /* Source */ = { isa = PBXGroup; children = ( - 73259AA7FEA14577AEF2DB550C3020EB /* IGListAdapter.h */, - 6ACF94F01EB36325B7E6582A24CE67E1 /* IGListAdapter.m */, - FE4F9D5E24C8E166CBE1324FB4EFE901 /* IGListAdapterDataSource.h */, - 8C9AC4FA89437FC74B5044CB6E09F330 /* IGListAdapterDelegate.h */, - 60379E52F4C982E1C790B6519E71C7C7 /* IGListAdapterUpdater.h */, - 64E8ACC5C6782B94FD1B95596927A543 /* IGListAdapterUpdater.m */, - 923F1BE703C78DB09D0F325460A4A2EA /* IGListAdapterUpdaterDelegate.h */, - 5317DB3BAAEE0CC7B2D2B105A879060D /* IGListAssert.h */, - BE4F9093FE09B54A0DC32E8161904775 /* IGListBatchUpdateData.h */, - D0AEE94B91F9849EEF961CC1C265C985 /* IGListBatchUpdateData.mm */, - 17FC1649F3BE2A7A920FF0C7D50B7EC2 /* IGListCollectionContext.h */, - 1FE4AA45BC45A8EF0F9FB575B19EE801 /* IGListCollectionView.h */, - 4B5597025F567F3628A6FE6AB07D53F3 /* IGListCollectionView.m */, - B3A4D0DCC742ED05F9B0EAD98B483829 /* IGListDiff.h */, - 4B14381CF1C8B474F904BED10858A3B1 /* IGListDiff.mm */, - 54A169D9E10ABA4A657E466A81CF5E96 /* IGListDiffable.h */, - E2B529498914743C310A5BF137656A18 /* IGListDisplayDelegate.h */, - 8CFC4E4785DC5CD494D3BA69EE0EF1C5 /* IGListExperiments.h */, - DBA04B01FE70BC1FC9B2AF5A04816653 /* IGListIndexPathResult.h */, - DD1EB6F6A5F5CF2DA79688B3A01F95BC /* IGListIndexPathResult.m */, - 84752D2DDFC17301AD69B035A1ABEB98 /* IGListIndexSetResult.h */, - B281B0B7972DE5D26848178203A718AE /* IGListIndexSetResult.m */, - 1DD75371720A47691326032C3842EA7D /* IGListKit.h */, - 7E7FEF0C49C387ED472744AB5E63D5C5 /* IGListMacros.h */, - 4F331B7F935DA82F2BA8F9EC9CDAC989 /* IGListMoveIndex.h */, - D37ACDCF54F63073142D7196E56946A3 /* IGListMoveIndex.m */, - A25B427B6865597BD60B14637B4DF317 /* IGListMoveIndexPath.h */, - 7F401C4ED6FD8A5953382E94BFDC1B04 /* IGListMoveIndexPath.m */, - CDA049308F02171E1FE2541EFF16E527 /* IGListReloadDataUpdater.h */, - EBFD4BC90748BE8DE367B6DCA73B982A /* IGListReloadDataUpdater.m */, - A48E8E2621D1D301DF15DC1EA7F25CB7 /* IGListScrollDelegate.h */, - 50D66D11EB993B3B287DA0B8DEE153B7 /* IGListSectionController.h */, - F5AD8343AC8B755A3258D6E45FFD2D8A /* IGListSectionController.m */, - C0D34FDB422AF09AA6F7813D34DA3DCD /* IGListSectionType.h */, - A6A48D5B55D7631327C124F538C6E068 /* IGListSingleSectionController.h */, - 91007FC1F36EE50D4609909509B4BE04 /* IGListSingleSectionController.m */, - B9B2C760A6B8BC4E2F9B9BC221585A06 /* IGListStackedSectionController.h */, - 22F3AD163D43B95418E4F734FDD061F4 /* IGListStackedSectionController.m */, - D7D841899F69CAEFE9CC75F4C742EB7F /* IGListSupplementaryViewSource.h */, - 5074228D8F3A063BF5EE38BBCDC854D8 /* IGListUpdatingDelegate.h */, - D9F947E7710011A32E4FA3C988472760 /* IGListWorkingRangeDelegate.h */, - 516F4D39676D39DB68711DFCCF99CD08 /* NSObject+IGListDiffable.h */, - 720FAF43FD40FA27160DB53AD4C8E73D /* NSObject+IGListDiffable.m */, - 568515C4F4B02B048840EBD06A1CC65D /* Internal */, + 082E59D92D62734B72D1DDC3A5C15A3F /* IGListAdapter.h */, + C5AEE1C40000E48F6BA5A13134908A3A /* IGListAdapter.m */, + FD774554CAECD4B6727C7474901F3603 /* IGListAdapterDataSource.h */, + D23E094B3D67F1B0E6E5B97741F3CA27 /* IGListAdapterDelegate.h */, + 9C79D692BCABA200CDF96AE4A22B633D /* IGListAdapterUpdater.h */, + E4682D0326028D1742954DF0ED0ECC51 /* IGListAdapterUpdater.m */, + 4DA6521BF7772A5EA3E951CEE4970AE3 /* IGListAdapterUpdaterDelegate.h */, + 1DE331AF5EE69F5505389A4B606026B0 /* IGListAssert.h */, + 33FDCD6A0E661FF92D0186B8809819D1 /* IGListBatchUpdateData.h */, + 14F41375D4095CBE1A26CBE60E845E2F /* IGListBatchUpdateData.mm */, + 0D8F0F47DE98C3252F16924EF2CDFE6D /* IGListCollectionContext.h */, + 7E009D402058A4557F4BD60EDA7621D5 /* IGListCollectionView.h */, + 8D7C8296520E9B1E9B23A02237B2B371 /* IGListCollectionView.m */, + 9E20BBC002825CE2FD5715F79DE91DD5 /* IGListDiff.h */, + 53C807CB982FACB90000DD53A994C24F /* IGListDiff.mm */, + DF71C4B0ECA6E21DB8448A7B79E9A85A /* IGListDiffable.h */, + 7116C46C152D97F96CE269437340AF86 /* IGListDisplayDelegate.h */, + 836082517258A9D41009E52839F7197D /* IGListExperiments.h */, + 667B5A2F952792A619FE387BF4329989 /* IGListIndexPathResult.h */, + E5E956D6176274C2D22F6B26C16D307B /* IGListIndexPathResult.m */, + DD0F31C66F1665645FFDF84FCD01944D /* IGListIndexSetResult.h */, + 75E3BF27752D3B23EA4375E7628DC77D /* IGListIndexSetResult.m */, + FFA6AA44B74879612E1411581AF4DEC7 /* IGListKit.h */, + A797E1D5C7D0E09DABA9DB838A2F822B /* IGListMacros.h */, + 1C247AE0AD292B1B21A1243672E0A1A5 /* IGListMoveIndex.h */, + AE3BC07368663FE65CB4B56914C5BCA7 /* IGListMoveIndex.m */, + D7085344BDCC7B4DBBB37FA006B80B89 /* IGListMoveIndexPath.h */, + 6E49A47118A1919487DADE4931F92474 /* IGListMoveIndexPath.m */, + 2E9009BE5D28B8C45381B6BFE8EFF6D0 /* IGListReloadDataUpdater.h */, + 35A851CF1D56275EDAD77284662184AB /* IGListReloadDataUpdater.m */, + 0C48B3D6C37870D8E7DB578128BF04DC /* IGListScrollDelegate.h */, + 1193C6D51D46D8DDA0BE2FD7E4EE35ED /* IGListSectionController.h */, + 1001B9578EF8CD484E47B583D8D7CD84 /* IGListSectionController.m */, + 01AE564E773788A8781A7D1EC6BE2B8A /* IGListSectionType.h */, + F3E397AD6485B00E5412DA38E2A259CC /* IGListSingleSectionController.h */, + 1C2D642B4A4985AE7BB64C0371E56243 /* IGListSingleSectionController.m */, + D84C423B4DFFB471D2F178702762F9AF /* IGListStackedSectionController.h */, + 6099CEC502FCB187B87F06ED64BBBC1D /* IGListStackedSectionController.m */, + 65D85554C94E6AF326DB80AC597949B0 /* IGListSupplementaryViewSource.h */, + A9F36E8FC50AEADB59AAD67BD7962588 /* IGListUpdatingDelegate.h */, + FE2BA5ED2BAD56B731D54C06AC00B72F /* IGListWorkingRangeDelegate.h */, + E0D42DAFA6A4A19EEA6CD58BA183E9D7 /* NSObject+IGListDiffable.h */, + F7C4A7A1D6CA44ACF7B060879859C0D3 /* NSObject+IGListDiffable.m */, + 36EFBC6A23BC1F7AE38FF774C39826A1 /* Internal */, ); + name = Source; path = Source; sourceTree = ""; }; - F22E6673D29C1778B1984CF7D4D871E9 /* Pods-IGListKitExamples */ = { + CF9909136132DE20E8D2AD0C67AA0C49 /* Products */ = { isa = PBXGroup; children = ( - ABF549428FEA18696E5358F599E11A24 /* Info.plist */, - DDF922EBFB237C1B42E8B07306D987E8 /* Pods-IGListKitExamples.modulemap */, - A7BBE69D34859663403DA26F14CC4DDB /* Pods-IGListKitExamples-acknowledgements.markdown */, - D803D538BF4074498E5ADB84A16E0395 /* Pods-IGListKitExamples-acknowledgements.plist */, - 2F5AE0385534EC7E6CA75003A7280492 /* Pods-IGListKitExamples-dummy.m */, - A851A4ACB8C0DE98BFFBC6FD4D1BACEE /* Pods-IGListKitExamples-frameworks.sh */, - 428C13C7C57B2D91F00D94ECF1FA71F8 /* Pods-IGListKitExamples-resources.sh */, - 52054AE893A0AE7FBFC54333D8ABD345 /* Pods-IGListKitExamples-umbrella.h */, - 1B2B14BA3AB402D9CC387EEB27A2F746 /* Pods-IGListKitExamples.debug.xcconfig */, - A198E265B2C6E673C7C9C5050F92D9F0 /* Pods-IGListKitExamples.release.xcconfig */, + 116948205344E279070B2977E925F803 /* IGListKit.framework */, + 3DFBEA9D0D85DB9366D3C949C20332DD /* Pods_IGListKitExamples.framework */, + 57D6B0172E92F207DDCC38AA57BBD76C /* Pods_IGListKitMessageExample.framework */, + 3546419AAFB29CE358FDE5691F031F9E /* Pods_IGListKitTodayExample.framework */, ); - name = "Pods-IGListKitExamples"; - path = "Target Support Files/Pods-IGListKitExamples"; + name = Products; sourceTree = ""; }; - F302CD3B306AF1ED96B9AF31FCDBC26C /* iOS */ = { + DAB5B0D31F1F31F2EA5708FF996EE588 /* Support Files */ = { isa = PBXGroup; children = ( - A2A6FF208CEC4C2861F1E9D42D651453 /* Foundation.framework */, - E86668F20F252C440D1015B816BE59C5 /* UIKit.framework */, + 561D1CAC9AE6D43A06CCEAFEC05B04DA /* IGListKit.modulemap */, + 891CE36E66A66905E25AD89B001B5648 /* IGListKit.xcconfig */, + 85FB0BDA4A7F33F3588C88434ECD2E94 /* IGListKit-dummy.m */, + 5B065D6991AF097908DF9824689FB9C4 /* IGListKit-prefix.pch */, + 82BBB8E0984E89E3CD3311E21D7F65D6 /* IGListKit-umbrella.h */, + BF8DCC2E99230AF598F30C8A54C525FB /* Info.plist */, + ); + name = "Support Files"; + path = "Example/Pods/Target Support Files/IGListKit"; + sourceTree = ""; + }; + E6EE98446B568159EE277B68FD442AF0 /* iOS */ = { + isa = PBXGroup; + children = ( + 616BEB51ECCAD129BDBCB7A956B56CC6 /* Foundation.framework */, + 7EC994CDC2D681BA26389F78A7E4B325 /* UIKit.framework */, ); name = iOS; sourceTree = ""; @@ -373,75 +463,108 @@ /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ - 53EBE39810518423DDF4C14A0AB25552 /* Headers */ = { + 0009F2E427E8D3AEACA5AB0514131AF2 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 35102F69615549F427FE2EC453149DAB /* IGListAdapter.h in Headers */, - 6B2EE19479243F984CE51F15ACCB1A33 /* IGListAdapterDataSource.h in Headers */, - 76B403D7072D98BED2AA6AA6C7827E39 /* IGListAdapterDelegate.h in Headers */, - 1EB6675BEF69B9E921CE4199DD7156D0 /* IGListAdapterInternal.h in Headers */, - 68A93F0E164CD1E9910C25698B5B0DC7 /* IGListAdapterProxy.h in Headers */, - BAB517802021813C296E2F2BA2C91FE2 /* IGListAdapterUpdater.h in Headers */, - A6091B575605FDBAD5E9E5645248FD66 /* IGListAdapterUpdaterDelegate.h in Headers */, - CCCD28F400F07B8C22AC80757491E13B /* IGListAdapterUpdaterInternal.h in Headers */, - 084B851CFFA9C0E2DF68D903E53E0EC8 /* IGListAssert.h in Headers */, - D46249EFD12F9C350961FEA1831DF20F /* IGListBatchUpdateData.h in Headers */, - 623527A4232D59FB38547902423B5AA2 /* IGListCollectionContext.h in Headers */, - 80AB64741918F4F2A7585C3C5FCBD98D /* IGListCollectionView.h in Headers */, - 503BDC35E6053B83D862316F3D8C935F /* IGListDiff.h in Headers */, - A01D6F5340CA1BD84E5DAB81B60A02A2 /* IGListDiffable.h in Headers */, - C4328DE47976156C06FB51E1FC1C79FA /* IGListDisplayDelegate.h in Headers */, - B01F1324E6269028CE385E78C26EF9D3 /* IGListDisplayHandler.h in Headers */, - B17B8BA5347B0717A112EB2BCE055293 /* IGListExperiments.h in Headers */, - 9EA7B904CC4B3E23C79B9B3909A51C2A /* IGListIndexPathResult.h in Headers */, - 0C27A4BED7FE0607F8E864854B0D4CB4 /* IGListIndexPathResultInternal.h in Headers */, - 931AB3AD8B295F26EDDB6FC6849EA247 /* IGListIndexSetResult.h in Headers */, - 1691094821EAD389A7A9C0BA79A970DB /* IGListIndexSetResultInternal.h in Headers */, - E01ABFB55E486E56D309DE5BAA801876 /* IGListKit-umbrella.h in Headers */, - F360C686D507AA39A221B314C92050B1 /* IGListKit.h in Headers */, - 444D6A0E181DF93311717CA41DB7B48A /* IGListMacros.h in Headers */, - 8F026EF7A1AB975A5411D2BDE5B4C081 /* IGListMoveIndex.h in Headers */, - 86B79ED8B51A8D5353E49A6C37DFE5CB /* IGListMoveIndexInternal.h in Headers */, - 6F06EF99F8A0B55F4E81D767EB7F4B36 /* IGListMoveIndexPath.h in Headers */, - 54EAA3B5C88905CD01B5FE2ADDF92FC6 /* IGListMoveIndexPathInternal.h in Headers */, - FD7CE90CC29F48232D88E3273B183752 /* IGListReloadDataUpdater.h in Headers */, - DBE42210054F8FDA69270F4EC611FD4C /* IGListScrollDelegate.h in Headers */, - 9F9C5D1351A6EB88531F759304A7A5D6 /* IGListSectionController.h in Headers */, - 6110D5294C734F5AF8FAF5AD4134789F /* IGListSectionControllerInternal.h in Headers */, - BF318B0B45ACAF2725C9AC468D256E3D /* IGListSectionMap.h in Headers */, - 6C43A407033E5A273E9E16EE7E334EB2 /* IGListSectionType.h in Headers */, - 2C58ED7F6EFFB13891EBAAF768E2C998 /* IGListSingleSectionController.h in Headers */, - 57FF7C6AED54D8A04C41DA36231BFC94 /* IGListStackedSectionController.h in Headers */, - B70560D9E6761A6E5666060E05DE071C /* IGListStackedSectionControllerInternal.h in Headers */, - 26750C29F741D0EF22EF396017265DC7 /* IGListSupplementaryViewSource.h in Headers */, - 1FD624CB427ECAEF7F1F9949E4B023AE /* IGListUpdatingDelegate.h in Headers */, - 83E3217B930A28021BC1DFC1DFD759A0 /* IGListWorkingRangeDelegate.h in Headers */, - 86BA72487680B4F3CFEB719F821D183A /* IGListWorkingRangeHandler.h in Headers */, - BFEEC2F47FC552E9E6EC80C984A8DE10 /* NSIndexSet+PrettyDescription.h in Headers */, - C7B337BF99A703262B38856C2A916613 /* NSObject+IGListDiffable.h in Headers */, - 9368BAE80054E3977919DCC164581318 /* UICollectionView+IGListBatchUpdateData.h in Headers */, + 75000A67FAE5194A808EC2D8D701CC8E /* IGListAdapter.h in Headers */, + 22A17D9784C14D8DD5A1EED7AFAF93FA /* IGListAdapterDataSource.h in Headers */, + ECA097208E20EFF9958E770B85A2777F /* IGListAdapterDelegate.h in Headers */, + 63E44C34556274554700CB64E3752300 /* IGListAdapterInternal.h in Headers */, + DBC4ED99271185BD33163C3C35EECA4C /* IGListAdapterProxy.h in Headers */, + 79DD3BEC4F26994808F4B708291EA820 /* IGListAdapterUpdater.h in Headers */, + 81DB1409A04343AA5E7D4387C2806C72 /* IGListAdapterUpdaterDelegate.h in Headers */, + B2B07B2CFD9CB2EC33CCA14854368C00 /* IGListAdapterUpdaterInternal.h in Headers */, + 1A4E1A1CB6336FD8D4860F0255A84E19 /* IGListAssert.h in Headers */, + 3078D3DBACBFD2CC6D2184BF88BCAFAD /* IGListBatchUpdateData.h in Headers */, + 02FD4C5495EBB07A03FA84A132A5D45C /* IGListCollectionContext.h in Headers */, + C9B30C305923438D4F5171ED03CEC483 /* IGListCollectionView.h in Headers */, + CF302D5A5C86BC17A36F7368BC2E4F18 /* IGListDiff.h in Headers */, + 4FC26BBF235D28B2A5F5B6309FE5936A /* IGListDiffable.h in Headers */, + 3B60C19F42DF03B5DC0E9ADB182FABD3 /* IGListDisplayDelegate.h in Headers */, + B843EE9504A7CEC862224D22D34A240E /* IGListDisplayHandler.h in Headers */, + 2A829436185BF8282D20F6CFB29065E7 /* IGListExperiments.h in Headers */, + 064A1A8FFB4ABF19068CA3780789B043 /* IGListIndexPathResult.h in Headers */, + 2C23E0F66B7E1C1F8D37D93A3FFBD4E0 /* IGListIndexPathResultInternal.h in Headers */, + 91FE5094076BCD5F00082082E6DE8084 /* IGListIndexSetResult.h in Headers */, + 0614CE98DF942497BF536C8648F93351 /* IGListIndexSetResultInternal.h in Headers */, + 95981CDF74D7AD863E7F8C3532850839 /* IGListKit-umbrella.h in Headers */, + C45C182E21F3398B458DB7A9C99DFF45 /* IGListKit.h in Headers */, + F13EBCFFF6329C713E28457CEA2F6818 /* IGListMacros.h in Headers */, + CDCCA3E3E375EDB3342251690CD052F0 /* IGListMoveIndex.h in Headers */, + 8A93CB107141878678FCBCE60429C62F /* IGListMoveIndexInternal.h in Headers */, + 17C0C840A8B9D1FD50FA407EE419E4D0 /* IGListMoveIndexPath.h in Headers */, + 72F56377D5CC348C4228A8CB058AF830 /* IGListMoveIndexPathInternal.h in Headers */, + 8A3B3A822CBCC5C301403DED2D065DEC /* IGListReloadDataUpdater.h in Headers */, + B1F33CF7BAF6B035172F0AD98CEAFE7F /* IGListScrollDelegate.h in Headers */, + E801D8DCF84428347CFF0F428241B267 /* IGListSectionController.h in Headers */, + C9549BB7BDAC0EC31EB2804F5FE7BC00 /* IGListSectionControllerInternal.h in Headers */, + 7A77DCC596C361613468F117DCFF425F /* IGListSectionMap.h in Headers */, + 08620A926A12C5C18637088543C9F2A6 /* IGListSectionType.h in Headers */, + 61766FB6312CF0C8C6CC7B58C163DB82 /* IGListSingleSectionController.h in Headers */, + 27570C13B6F8420258B5FCC2F6620D4D /* IGListStackedSectionController.h in Headers */, + A886AA2548040EDBFFEDEDA310CBDBEA /* IGListStackedSectionControllerInternal.h in Headers */, + FA3D8136BFF963A80623A2D9C1613744 /* IGListSupplementaryViewSource.h in Headers */, + C98CD17D4DA7CE4D32366790C5438346 /* IGListUpdatingDelegate.h in Headers */, + 1DDAF17BDB3240FFD24E2E8897935122 /* IGListWorkingRangeDelegate.h in Headers */, + 42D8BD08D4E77F189EA13239DBB03F65 /* IGListWorkingRangeHandler.h in Headers */, + AD51AC5022C8C84A3F23026B0CD036D6 /* NSObject+IGListDiffable.h in Headers */, + 9B4175900859EFF6CEFADD3078B17360 /* UICollectionView+IGListBatchUpdateData.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - B207714E2837D513687F9EE68AED37E4 /* Headers */ = { + A8FD7A8DF5CE870AA2A619FE79FE81D9 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - FF9FF8C3E7C149B40D25B5B2BB530C27 /* Pods-IGListKitExamples-umbrella.h in Headers */, + E353B40949D9675B8B2B03C7569F96F5 /* Pods-IGListKitMessageExample-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F3DD1C6E9E3232E5D8AB2ED431AA4C96 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + B737133A4230ACB664806CF20F03FAD1 /* Pods-IGListKitTodayExample-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FCF6DC82D5858E45FAEE513F9E764AAD /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 1A89AF7CCCD65D9D5B946363776D05AE /* Pods-IGListKitExamples-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ - 26932F09684B706888A7BF05E69D387C /* IGListKit */ = { + 401DEFF5B4204434A3367C3A45C172EE /* Pods-IGListKitMessageExample */ = { isa = PBXNativeTarget; - buildConfigurationList = 535D892140575DCAAE9094BF475E7520 /* Build configuration list for PBXNativeTarget "IGListKit" */; + buildConfigurationList = 7DD0F06330B7CFF95DBE709F180B8869 /* Build configuration list for PBXNativeTarget "Pods-IGListKitMessageExample" */; buildPhases = ( - E5B604A4F391F089A0370DD183AC19E3 /* Sources */, - FE924FF264CD5BDB6DFE9C2ACA63FCAC /* Frameworks */, - 53EBE39810518423DDF4C14A0AB25552 /* Headers */, + 2FF6C4068B8331D4FA2A47EB9F42A336 /* Sources */, + E9A8D02E745CDFBE4784E186849B8E0E /* Frameworks */, + A8FD7A8DF5CE870AA2A619FE79FE81D9 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + 36C541B7631C30D80576C418E9F06C18 /* PBXTargetDependency */, + ); + name = "Pods-IGListKitMessageExample"; + productName = "Pods-IGListKitMessageExample"; + productReference = 57D6B0172E92F207DDCC38AA57BBD76C /* Pods_IGListKitMessageExample.framework */; + productType = "com.apple.product-type.framework"; + }; + 69D4D7AE264E7E3080B0DF650DDE7F16 /* IGListKit */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1FF217415000FF2BF40B598E968B8ECD /* Build configuration list for PBXNativeTarget "IGListKit" */; + buildPhases = ( + A4C4F765A83FA6B2EDF2034295C3E65D /* Sources */, + 4A5EAB00BE8AF762691C11C9B294D9A3 /* Frameworks */, + 0009F2E427E8D3AEACA5AB0514131AF2 /* Headers */, ); buildRules = ( ); @@ -449,25 +572,43 @@ ); name = IGListKit; productName = IGListKit; - productReference = 9D11DCAE06F644E6CCE659622CD8E616 /* IGListKit.framework */; + productReference = 116948205344E279070B2977E925F803 /* IGListKit.framework */; productType = "com.apple.product-type.framework"; }; - 399B3DA0A0B4EE07A34985CAE12415EA /* Pods-IGListKitExamples */ = { + 6B7DA8C024D099705CF771FF16E6FC16 /* Pods-IGListKitExamples */ = { isa = PBXNativeTarget; - buildConfigurationList = D5ABECD9BBE4FF7324D45ECEE77ED0B8 /* Build configuration list for PBXNativeTarget "Pods-IGListKitExamples" */; + buildConfigurationList = 447A9F6E709F690B1574347D9E329E3D /* Build configuration list for PBXNativeTarget "Pods-IGListKitExamples" */; buildPhases = ( - C2EC7EB6182BF2E3B3BB74E91A191E66 /* Sources */, - AA75830E6081F3DABCD8A9D38D8D20E7 /* Frameworks */, - B207714E2837D513687F9EE68AED37E4 /* Headers */, + 0F2973A0EC5CE783280F7EAA54947BA5 /* Sources */, + D7057175063065567057895AB005C590 /* Frameworks */, + FCF6DC82D5858E45FAEE513F9E764AAD /* Headers */, ); buildRules = ( ); dependencies = ( - E4B48C859ACB78DD3BE68BBEBA62D2D0 /* PBXTargetDependency */, + 9B463355891949F736B3B5D678FE8D02 /* PBXTargetDependency */, ); name = "Pods-IGListKitExamples"; productName = "Pods-IGListKitExamples"; - productReference = C7F454644FEBF5DB647AE1728D1FD067 /* Pods_IGListKitExamples.framework */; + productReference = 3DFBEA9D0D85DB9366D3C949C20332DD /* Pods_IGListKitExamples.framework */; + productType = "com.apple.product-type.framework"; + }; + FA6C50153578D5634418D6966B7AAEDD /* Pods-IGListKitTodayExample */ = { + isa = PBXNativeTarget; + buildConfigurationList = 0FE3BD27B2D26DDCF7A53630AB4BE0DB /* Build configuration list for PBXNativeTarget "Pods-IGListKitTodayExample" */; + buildPhases = ( + 8361670856E51102C9B2F59306C2B3B3 /* Sources */, + B2FDE9ED50A78E4384C3AB5BADC034B3 /* Frameworks */, + F3DD1C6E9E3232E5D8AB2ED431AA4C96 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + BFAF67A08B878C67ABE4BF370ECEA0C1 /* PBXTargetDependency */, + ); + name = "Pods-IGListKitTodayExample"; + productName = "Pods-IGListKitTodayExample"; + productReference = 3546419AAFB29CE358FDE5691F031F9E /* Pods_IGListKitTodayExample.framework */; productType = "com.apple.product-type.framework"; }; /* End PBXNativeTarget section */ @@ -487,61 +628,90 @@ en, ); mainGroup = 7DB346D0F39D3F0E887471402A8071AB; - productRefGroup = 61F96534B3AFE724944526CC9F6F2EFE /* Products */; + productRefGroup = CF9909136132DE20E8D2AD0C67AA0C49 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( - 26932F09684B706888A7BF05E69D387C /* IGListKit */, - 399B3DA0A0B4EE07A34985CAE12415EA /* Pods-IGListKitExamples */, + 69D4D7AE264E7E3080B0DF650DDE7F16 /* IGListKit */, + 6B7DA8C024D099705CF771FF16E6FC16 /* Pods-IGListKitExamples */, + 401DEFF5B4204434A3367C3A45C172EE /* Pods-IGListKitMessageExample */, + FA6C50153578D5634418D6966B7AAEDD /* Pods-IGListKitTodayExample */, ); }; /* End PBXProject section */ /* Begin PBXSourcesBuildPhase section */ - C2EC7EB6182BF2E3B3BB74E91A191E66 /* Sources */ = { + 0F2973A0EC5CE783280F7EAA54947BA5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C4C4C1B02AFD7277F00A40570658152C /* Pods-IGListKitExamples-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2FF6C4068B8331D4FA2A47EB9F42A336 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - B7FADDD58154CEA589481E450BD88E33 /* Pods-IGListKitExamples-dummy.m in Sources */, + 4DC076C43C4AA5A3C88EEC49F5097581 /* Pods-IGListKitMessageExample-dummy.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - E5B604A4F391F089A0370DD183AC19E3 /* Sources */ = { + 8361670856E51102C9B2F59306C2B3B3 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - BC0126520E73770835746D3B1B613938 /* IGListAdapter.m in Sources */, - 171501700F6A914CD4C44E3666398BB5 /* IGListAdapterProxy.m in Sources */, - BF4804E0DD82EA483FF3C82F8DFCABBD /* IGListAdapterUpdater.m in Sources */, - 5455F7C71EB93A534D8A09AAFE8EF0FE /* IGListBatchUpdateData.mm in Sources */, - 4C6CC1B183686EB9EE4A7FF40CAFF697 /* IGListCollectionView.m in Sources */, - 25FDCBDCEA5575091B36BFE4B59D04CA /* IGListDiff.mm in Sources */, - 1CCB2FEACC2123958F5A0E39F70659B5 /* IGListDisplayHandler.m in Sources */, - 2912A571DF503B64C589EC9A44BA4B39 /* IGListIndexPathResult.m in Sources */, - EA5AEB7F2DADFF1BA74A38860AA60BA5 /* IGListIndexSetResult.m in Sources */, - C47B57F6C4A0B47A302C95C9FBD5BFDE /* IGListKit-dummy.m in Sources */, - 54CFA8A4442E7B0BB4C67FE811481E4C /* IGListMoveIndex.m in Sources */, - 32DA59CCC51F3C4A5239E87A45351EEE /* IGListMoveIndexPath.m in Sources */, - F5383C2327F50B07F0904BFE6EB496C8 /* IGListReloadDataUpdater.m in Sources */, - 135EAE77737104157F6CC0655BBA0ABA /* IGListSectionController.m in Sources */, - 026755843D7FB53E35679B703EFBBF6E /* IGListSectionMap.m in Sources */, - 213FF484E5786DD35F2A932774C57707 /* IGListSingleSectionController.m in Sources */, - 54E0CADE21353023E6F071C5FB164902 /* IGListStackedSectionController.m in Sources */, - 725B0E02B9D828F61443072352992F54 /* IGListWorkingRangeHandler.mm in Sources */, - F7023388DF86747C3752D4BCFFD9BE98 /* NSIndexSet+PrettyDescription.m in Sources */, - BA98207EA92AA990BE64F3C8970CBC9A /* NSObject+IGListDiffable.m in Sources */, - 0147435D65030952AE49DEC4E017B23D /* UICollectionView+IGListBatchUpdateData.m in Sources */, + B718064EE1D4B6E9B8212A936CA8EA75 /* Pods-IGListKitTodayExample-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A4C4F765A83FA6B2EDF2034295C3E65D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + BCDB1B4A86EADED693F540DF34112AD3 /* IGListAdapter.m in Sources */, + ABE4853E18CA830382A2462837E3EBED /* IGListAdapterProxy.m in Sources */, + 8AB84DCBFC8023C35C5AB2138D22C93D /* IGListAdapterUpdater.m in Sources */, + FC144585E390A54800B24AC3F0540DD8 /* IGListBatchUpdateData.mm in Sources */, + 2F4DD4F90E39BF5409ABDFBCEF68D5E7 /* IGListCollectionView.m in Sources */, + 73B8129B5A89D75D7EB7FE0EC324C751 /* IGListDiff.mm in Sources */, + 0201DC2443EAB9E8EFD7A4A9A9CFECC5 /* IGListDisplayHandler.m in Sources */, + ED78B12343068A5A8CF7D2145C236D7A /* IGListIndexPathResult.m in Sources */, + 25CA661803B75AB0476991E21BA42770 /* IGListIndexSetResult.m in Sources */, + 8487DEE3683A65AAD6452E22B0533ECB /* IGListKit-dummy.m in Sources */, + 67EB1BD5E83AAF5CA897879A9A9C2332 /* IGListMoveIndex.m in Sources */, + 7E06046B354A6E26CA1BFC524D7FB48A /* IGListMoveIndexPath.m in Sources */, + A6DED991868B6854BEBC3C7250D3A446 /* IGListReloadDataUpdater.m in Sources */, + 8F8381656B8CDF4B0B5A3840B7DA160D /* IGListSectionController.m in Sources */, + 33246AA4C1F98CDBD8C95AA74A8D68BD /* IGListSectionMap.m in Sources */, + F6C6EDF4358AF137CA360ADE80BC8F5D /* IGListSingleSectionController.m in Sources */, + D3FFC74A899A28C284E3CA2E7D834DA3 /* IGListStackedSectionController.m in Sources */, + 60FBA584D762726D2E2431593C3411E2 /* IGListWorkingRangeHandler.mm in Sources */, + FB761405D4AD376F952AA615DF5D1F31 /* NSObject+IGListDiffable.m in Sources */, + CBB31E3DD44CCE559CD453246280A6FE /* UICollectionView+IGListBatchUpdateData.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - E4B48C859ACB78DD3BE68BBEBA62D2D0 /* PBXTargetDependency */ = { + 36C541B7631C30D80576C418E9F06C18 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = IGListKit; + target = 69D4D7AE264E7E3080B0DF650DDE7F16 /* IGListKit */; + targetProxy = 42B122D03058E7C3E34ACF0AC2A72140 /* PBXContainerItemProxy */; + }; + 9B463355891949F736B3B5D678FE8D02 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = IGListKit; - target = 26932F09684B706888A7BF05E69D387C /* IGListKit */; - targetProxy = 5A4D93DEC315EA1419504908E8F1310B /* PBXContainerItemProxy */; + target = 69D4D7AE264E7E3080B0DF650DDE7F16 /* IGListKit */; + targetProxy = A0A5426482C447F640D6A192E71D5F5B /* PBXContainerItemProxy */; + }; + BFAF67A08B878C67ABE4BF370ECEA0C1 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = IGListKit; + target = 69D4D7AE264E7E3080B0DF650DDE7F16 /* IGListKit */; + targetProxy = 7D332B346FFC0D5E5159546D185DAFEF /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ @@ -590,6 +760,42 @@ }; name = Debug; }; + 197EBCEB0EC5F7CAA6982D73F96C09CB /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4F9A8086AF09CCA586431BFEE5DE2CA3 /* Pods-IGListKitMessageExample.debug.xcconfig */; + buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = "Target Support Files/Pods-IGListKitMessageExample/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-IGListKitMessageExample/Pods-IGListKitMessageExample.modulemap"; + MTL_ENABLE_DEBUG_INFO = YES; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = Pods_IGListKitMessageExample; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; 44CDBB6D11DE06DB64D6268622BDC47E /* Release */ = { isa = XCBuildConfiguration; buildSettings = { @@ -630,15 +836,16 @@ }; name = Release; }; - 6D8BEF09A2BC418CD8BBAB86D254BC18 /* Debug */ = { + 5F81FA6A6FEB18F9AD2AC1944A85DFCA /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 891CE36E66A66905E25AD89B001B5648 /* IGListKit.xcconfig */; buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = dwarf; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -651,7 +858,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MODULEMAP_FILE = "Target Support Files/IGListKit/IGListKit.modulemap"; - MTL_ENABLE_DEBUG_INFO = YES; + MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_NAME = IGListKit; SDKROOT = iphoneos; SKIP_INSTALL = YES; @@ -660,17 +867,17 @@ VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; - name = Debug; + name = Release; }; - 81B111721A36CCF4CD5432B606E638FE /* Release */ = { + 626865CE4C99FBA9E1F5FFE378E50648 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = A198E265B2C6E673C7C9C5050F92D9F0 /* Pods-IGListKitExamples.release.xcconfig */; + baseConfigurationReference = E1915F3ED5785508E2E252B0D5CD0AB9 /* Pods-IGListKitExamples.debug.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -683,7 +890,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MACH_O_TYPE = staticlib; MODULEMAP_FILE = "Target Support Files/Pods-IGListKitExamples/Pods-IGListKitExamples.modulemap"; - MTL_ENABLE_DEBUG_INFO = NO; + MTL_ENABLE_DEBUG_INFO = YES; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PODS_ROOT = "$(SRCROOT)"; @@ -695,12 +902,13 @@ VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; - name = Release; + name = Debug; }; - C197420E85C6EB8A3C2C625941CB7B61 /* Debug */ = { + ACA8A168549269FFC475C4357D635084 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 1B2B14BA3AB402D9CC387EEB27A2F746 /* Pods-IGListKitExamples.debug.xcconfig */; + baseConfigurationReference = 5EC090A99FE4CA3786E651AF9C907913 /* Pods-IGListKitTodayExample.debug.xcconfig */; buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; @@ -712,13 +920,84 @@ DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = "Target Support Files/Pods-IGListKitTodayExample/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-IGListKitTodayExample/Pods-IGListKitTodayExample.modulemap"; + MTL_ENABLE_DEBUG_INFO = YES; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = Pods_IGListKitTodayExample; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + B0E086482AB747F3C6AE0BC7D1AD0034 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 65A1389E308E5581D73D099A74A15628 /* Pods-IGListKitMessageExample.release.xcconfig */; + buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = "Target Support Files/Pods-IGListKitMessageExample/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-IGListKitMessageExample/Pods-IGListKitMessageExample.modulemap"; + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = Pods_IGListKitMessageExample; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + B43A2433B75DE95CE8C94635DAF98E9C /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 568FA20FCC9D77DF4FF3A77159CB66AA /* Pods-IGListKitExamples.release.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = "Target Support Files/Pods-IGListKitExamples/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MACH_O_TYPE = staticlib; MODULEMAP_FILE = "Target Support Files/Pods-IGListKitExamples/Pods-IGListKitExamples.modulemap"; - MTL_ENABLE_DEBUG_INFO = YES; + MTL_ENABLE_DEBUG_INFO = NO; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PODS_ROOT = "$(SRCROOT)"; @@ -730,12 +1009,13 @@ VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; - name = Debug; + name = Release; }; - EAC7D6220A71D1FDCB6309C89D9A46AD /* Release */ = { + BB299855973C01172BF9A53C852AC211 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 891CE36E66A66905E25AD89B001B5648 /* IGListKit.xcconfig */; + baseConfigurationReference = 922574DF06D0AD5E3964986609327D1F /* Pods-IGListKitTodayExample.release.xcconfig */; buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; @@ -747,13 +1027,49 @@ DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = "Target Support Files/Pods-IGListKitTodayExample/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-IGListKitTodayExample/Pods-IGListKitTodayExample.modulemap"; + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = Pods_IGListKitTodayExample; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + CA55F813F4C8A3EC251D342E261781E1 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 891CE36E66A66905E25AD89B001B5648 /* IGListKit.xcconfig */; + buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; GCC_PREFIX_HEADER = "Target Support Files/IGListKit/IGListKit-prefix.pch"; INFOPLIST_FILE = "Target Support Files/IGListKit/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MODULEMAP_FILE = "Target Support Files/IGListKit/IGListKit.modulemap"; - MTL_ENABLE_DEBUG_INFO = NO; + MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_NAME = IGListKit; SDKROOT = iphoneos; SKIP_INSTALL = YES; @@ -762,11 +1078,29 @@ VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; - name = Release; + name = Debug; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 0FE3BD27B2D26DDCF7A53630AB4BE0DB /* Build configuration list for PBXNativeTarget "Pods-IGListKitTodayExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + ACA8A168549269FFC475C4357D635084 /* Debug */, + BB299855973C01172BF9A53C852AC211 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1FF217415000FF2BF40B598E968B8ECD /* Build configuration list for PBXNativeTarget "IGListKit" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + CA55F813F4C8A3EC251D342E261781E1 /* Debug */, + 5F81FA6A6FEB18F9AD2AC1944A85DFCA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -776,20 +1110,20 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 535D892140575DCAAE9094BF475E7520 /* Build configuration list for PBXNativeTarget "IGListKit" */ = { + 447A9F6E709F690B1574347D9E329E3D /* Build configuration list for PBXNativeTarget "Pods-IGListKitExamples" */ = { isa = XCConfigurationList; buildConfigurations = ( - 6D8BEF09A2BC418CD8BBAB86D254BC18 /* Debug */, - EAC7D6220A71D1FDCB6309C89D9A46AD /* Release */, + 626865CE4C99FBA9E1F5FFE378E50648 /* Debug */, + B43A2433B75DE95CE8C94635DAF98E9C /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - D5ABECD9BBE4FF7324D45ECEE77ED0B8 /* Build configuration list for PBXNativeTarget "Pods-IGListKitExamples" */ = { + 7DD0F06330B7CFF95DBE709F180B8869 /* Build configuration list for PBXNativeTarget "Pods-IGListKitMessageExample" */ = { isa = XCConfigurationList; buildConfigurations = ( - C197420E85C6EB8A3C2C625941CB7B61 /* Debug */, - 81B111721A36CCF4CD5432B606E638FE /* Release */, + 197EBCEB0EC5F7CAA6982D73F96C09CB /* Debug */, + B0E086482AB747F3C6AE0BC7D1AD0034 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; diff --git a/Example/Pods/Target Support Files/Pods-IGListKitMessageExample/Info.plist b/Example/Pods/Target Support Files/Pods-IGListKitMessageExample/Info.plist new file mode 100644 index 000000000..2243fe6e2 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-IGListKitMessageExample/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Example/Pods/Target Support Files/Pods-IGListKitMessageExample/Pods-IGListKitMessageExample-acknowledgements.markdown b/Example/Pods/Target Support Files/Pods-IGListKitMessageExample/Pods-IGListKitMessageExample-acknowledgements.markdown new file mode 100644 index 000000000..2c79cadac --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-IGListKitMessageExample/Pods-IGListKitMessageExample-acknowledgements.markdown @@ -0,0 +1,37 @@ +# Acknowledgements +This application makes use of the following third party libraries: + +## IGListKit + +BSD License + +For `IGListKit` software + +Copyright (c) 2016, Facebook, Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name Facebook nor the names of its contributors may be used to + endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Generated by CocoaPods - https://cocoapods.org diff --git a/Example/Pods/Target Support Files/Pods-IGListKitMessageExample/Pods-IGListKitMessageExample-acknowledgements.plist b/Example/Pods/Target Support Files/Pods-IGListKitMessageExample/Pods-IGListKitMessageExample-acknowledgements.plist new file mode 100644 index 000000000..cf1beb3f9 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-IGListKitMessageExample/Pods-IGListKitMessageExample-acknowledgements.plist @@ -0,0 +1,69 @@ + + + + + PreferenceSpecifiers + + + FooterText + This application makes use of the following third party libraries: + Title + Acknowledgements + Type + PSGroupSpecifier + + + FooterText + BSD License + +For `IGListKit` software + +Copyright (c) 2016, Facebook, Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name Facebook nor the names of its contributors may be used to + endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + License + BSD + Title + IGListKit + Type + PSGroupSpecifier + + + FooterText + Generated by CocoaPods - https://cocoapods.org + Title + + Type + PSGroupSpecifier + + + StringsTable + Acknowledgements + Title + Acknowledgements + + diff --git a/Example/Pods/Target Support Files/Pods-IGListKitMessageExample/Pods-IGListKitMessageExample-dummy.m b/Example/Pods/Target Support Files/Pods-IGListKitMessageExample/Pods-IGListKitMessageExample-dummy.m new file mode 100644 index 000000000..1f30f1f31 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-IGListKitMessageExample/Pods-IGListKitMessageExample-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_IGListKitMessageExample : NSObject +@end +@implementation PodsDummy_Pods_IGListKitMessageExample +@end diff --git a/Example/Pods/Target Support Files/Pods-IGListKitMessageExample/Pods-IGListKitMessageExample-resources.sh b/Example/Pods/Target Support Files/Pods-IGListKitMessageExample/Pods-IGListKitMessageExample-resources.sh new file mode 100755 index 000000000..25e9d3775 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-IGListKitMessageExample/Pods-IGListKitMessageExample-resources.sh @@ -0,0 +1,96 @@ +#!/bin/sh +set -e + +mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + +RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt +> "$RESOURCES_TO_COPY" + +XCASSET_FILES=() + +case "${TARGETED_DEVICE_FAMILY}" in + 1,2) + TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" + ;; + 1) + TARGET_DEVICE_ARGS="--target-device iphone" + ;; + 2) + TARGET_DEVICE_ARGS="--target-device ipad" + ;; + *) + TARGET_DEVICE_ARGS="--target-device mac" + ;; +esac + +install_resource() +{ + if [[ "$1" = /* ]] ; then + RESOURCE_PATH="$1" + else + RESOURCE_PATH="${PODS_ROOT}/$1" + fi + if [[ ! -e "$RESOURCE_PATH" ]] ; then + cat << EOM +error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. +EOM + exit 1 + fi + case $RESOURCE_PATH in + *.storyboard) + echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" + ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} + ;; + *.xib) + echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" + ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} + ;; + *.framework) + echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + echo "rsync -av $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + rsync -av "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + ;; + *.xcdatamodel) + echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" + xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" + ;; + *.xcdatamodeld) + echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" + xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" + ;; + *.xcmappingmodel) + echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" + xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" + ;; + *.xcassets) + ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" + XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") + ;; + *) + echo "$RESOURCE_PATH" + echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" + ;; + esac +} + +mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then + mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +fi +rm -f "$RESOURCES_TO_COPY" + +if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] +then + # Find all other xcassets (this unfortunately includes those of path pods and other targets). + OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) + while read line; do + if [[ $line != "${PODS_ROOT}*" ]]; then + XCASSET_FILES+=("$line") + fi + done <<<"$OTHER_XCASSETS" + + printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +fi diff --git a/Example/Pods/Target Support Files/Pods-IGListKitMessageExample/Pods-IGListKitMessageExample-umbrella.h b/Example/Pods/Target Support Files/Pods-IGListKitMessageExample/Pods-IGListKitMessageExample-umbrella.h new file mode 100644 index 000000000..71e9f7e93 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-IGListKitMessageExample/Pods-IGListKitMessageExample-umbrella.h @@ -0,0 +1,8 @@ +#ifdef __OBJC__ +#import +#endif + + +FOUNDATION_EXPORT double Pods_IGListKitMessageExampleVersionNumber; +FOUNDATION_EXPORT const unsigned char Pods_IGListKitMessageExampleVersionString[]; + diff --git a/Example/Pods/Target Support Files/Pods-IGListKitMessageExample/Pods-IGListKitMessageExample.debug.xcconfig b/Example/Pods/Target Support Files/Pods-IGListKitMessageExample/Pods-IGListKitMessageExample.debug.xcconfig new file mode 100644 index 000000000..76789ae5c --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-IGListKitMessageExample/Pods-IGListKitMessageExample.debug.xcconfig @@ -0,0 +1,9 @@ +ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO +FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/IGListKit" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' +OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/IGListKit/IGListKit.framework/Headers" +OTHER_LDFLAGS = $(inherited) -framework "IGListKit" +PODS_BUILD_DIR = $BUILD_DIR +PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT}/Pods diff --git a/Example/Pods/Target Support Files/Pods-IGListKitMessageExample/Pods-IGListKitMessageExample.modulemap b/Example/Pods/Target Support Files/Pods-IGListKitMessageExample/Pods-IGListKitMessageExample.modulemap new file mode 100644 index 000000000..ab6bd6d8b --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-IGListKitMessageExample/Pods-IGListKitMessageExample.modulemap @@ -0,0 +1,6 @@ +framework module Pods_IGListKitMessageExample { + umbrella header "Pods-IGListKitMessageExample-umbrella.h" + + export * + module * { export * } +} diff --git a/Example/Pods/Target Support Files/Pods-IGListKitMessageExample/Pods-IGListKitMessageExample.release.xcconfig b/Example/Pods/Target Support Files/Pods-IGListKitMessageExample/Pods-IGListKitMessageExample.release.xcconfig new file mode 100644 index 000000000..76789ae5c --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-IGListKitMessageExample/Pods-IGListKitMessageExample.release.xcconfig @@ -0,0 +1,9 @@ +ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO +FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/IGListKit" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' +OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/IGListKit/IGListKit.framework/Headers" +OTHER_LDFLAGS = $(inherited) -framework "IGListKit" +PODS_BUILD_DIR = $BUILD_DIR +PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT}/Pods diff --git a/Example/Pods/Target Support Files/Pods-IGListKitTodayExample/Info.plist b/Example/Pods/Target Support Files/Pods-IGListKitTodayExample/Info.plist new file mode 100644 index 000000000..2243fe6e2 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-IGListKitTodayExample/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Example/Pods/Target Support Files/Pods-IGListKitTodayExample/Pods-IGListKitTodayExample-acknowledgements.markdown b/Example/Pods/Target Support Files/Pods-IGListKitTodayExample/Pods-IGListKitTodayExample-acknowledgements.markdown new file mode 100644 index 000000000..2c79cadac --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-IGListKitTodayExample/Pods-IGListKitTodayExample-acknowledgements.markdown @@ -0,0 +1,37 @@ +# Acknowledgements +This application makes use of the following third party libraries: + +## IGListKit + +BSD License + +For `IGListKit` software + +Copyright (c) 2016, Facebook, Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name Facebook nor the names of its contributors may be used to + endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Generated by CocoaPods - https://cocoapods.org diff --git a/Example/Pods/Target Support Files/Pods-IGListKitTodayExample/Pods-IGListKitTodayExample-acknowledgements.plist b/Example/Pods/Target Support Files/Pods-IGListKitTodayExample/Pods-IGListKitTodayExample-acknowledgements.plist new file mode 100644 index 000000000..cf1beb3f9 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-IGListKitTodayExample/Pods-IGListKitTodayExample-acknowledgements.plist @@ -0,0 +1,69 @@ + + + + + PreferenceSpecifiers + + + FooterText + This application makes use of the following third party libraries: + Title + Acknowledgements + Type + PSGroupSpecifier + + + FooterText + BSD License + +For `IGListKit` software + +Copyright (c) 2016, Facebook, Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name Facebook nor the names of its contributors may be used to + endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + License + BSD + Title + IGListKit + Type + PSGroupSpecifier + + + FooterText + Generated by CocoaPods - https://cocoapods.org + Title + + Type + PSGroupSpecifier + + + StringsTable + Acknowledgements + Title + Acknowledgements + + diff --git a/Example/Pods/Target Support Files/Pods-IGListKitTodayExample/Pods-IGListKitTodayExample-dummy.m b/Example/Pods/Target Support Files/Pods-IGListKitTodayExample/Pods-IGListKitTodayExample-dummy.m new file mode 100644 index 000000000..0a387e5a3 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-IGListKitTodayExample/Pods-IGListKitTodayExample-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_IGListKitTodayExample : NSObject +@end +@implementation PodsDummy_Pods_IGListKitTodayExample +@end diff --git a/Example/Pods/Target Support Files/Pods-IGListKitTodayExample/Pods-IGListKitTodayExample-resources.sh b/Example/Pods/Target Support Files/Pods-IGListKitTodayExample/Pods-IGListKitTodayExample-resources.sh new file mode 100755 index 000000000..25e9d3775 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-IGListKitTodayExample/Pods-IGListKitTodayExample-resources.sh @@ -0,0 +1,96 @@ +#!/bin/sh +set -e + +mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + +RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt +> "$RESOURCES_TO_COPY" + +XCASSET_FILES=() + +case "${TARGETED_DEVICE_FAMILY}" in + 1,2) + TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" + ;; + 1) + TARGET_DEVICE_ARGS="--target-device iphone" + ;; + 2) + TARGET_DEVICE_ARGS="--target-device ipad" + ;; + *) + TARGET_DEVICE_ARGS="--target-device mac" + ;; +esac + +install_resource() +{ + if [[ "$1" = /* ]] ; then + RESOURCE_PATH="$1" + else + RESOURCE_PATH="${PODS_ROOT}/$1" + fi + if [[ ! -e "$RESOURCE_PATH" ]] ; then + cat << EOM +error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. +EOM + exit 1 + fi + case $RESOURCE_PATH in + *.storyboard) + echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" + ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} + ;; + *.xib) + echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" + ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} + ;; + *.framework) + echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + echo "rsync -av $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + rsync -av "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + ;; + *.xcdatamodel) + echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" + xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" + ;; + *.xcdatamodeld) + echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" + xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" + ;; + *.xcmappingmodel) + echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" + xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" + ;; + *.xcassets) + ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" + XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") + ;; + *) + echo "$RESOURCE_PATH" + echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" + ;; + esac +} + +mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then + mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +fi +rm -f "$RESOURCES_TO_COPY" + +if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] +then + # Find all other xcassets (this unfortunately includes those of path pods and other targets). + OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) + while read line; do + if [[ $line != "${PODS_ROOT}*" ]]; then + XCASSET_FILES+=("$line") + fi + done <<<"$OTHER_XCASSETS" + + printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +fi diff --git a/Example/Pods/Target Support Files/Pods-IGListKitTodayExample/Pods-IGListKitTodayExample-umbrella.h b/Example/Pods/Target Support Files/Pods-IGListKitTodayExample/Pods-IGListKitTodayExample-umbrella.h new file mode 100644 index 000000000..5297467ee --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-IGListKitTodayExample/Pods-IGListKitTodayExample-umbrella.h @@ -0,0 +1,8 @@ +#ifdef __OBJC__ +#import +#endif + + +FOUNDATION_EXPORT double Pods_IGListKitTodayExampleVersionNumber; +FOUNDATION_EXPORT const unsigned char Pods_IGListKitTodayExampleVersionString[]; + diff --git a/Example/Pods/Target Support Files/Pods-IGListKitTodayExample/Pods-IGListKitTodayExample.debug.xcconfig b/Example/Pods/Target Support Files/Pods-IGListKitTodayExample/Pods-IGListKitTodayExample.debug.xcconfig new file mode 100644 index 000000000..76789ae5c --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-IGListKitTodayExample/Pods-IGListKitTodayExample.debug.xcconfig @@ -0,0 +1,9 @@ +ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO +FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/IGListKit" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' +OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/IGListKit/IGListKit.framework/Headers" +OTHER_LDFLAGS = $(inherited) -framework "IGListKit" +PODS_BUILD_DIR = $BUILD_DIR +PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT}/Pods diff --git a/Example/Pods/Target Support Files/Pods-IGListKitTodayExample/Pods-IGListKitTodayExample.modulemap b/Example/Pods/Target Support Files/Pods-IGListKitTodayExample/Pods-IGListKitTodayExample.modulemap new file mode 100644 index 000000000..d06a975ea --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-IGListKitTodayExample/Pods-IGListKitTodayExample.modulemap @@ -0,0 +1,6 @@ +framework module Pods_IGListKitTodayExample { + umbrella header "Pods-IGListKitTodayExample-umbrella.h" + + export * + module * { export * } +} diff --git a/Example/Pods/Target Support Files/Pods-IGListKitTodayExample/Pods-IGListKitTodayExample.release.xcconfig b/Example/Pods/Target Support Files/Pods-IGListKitTodayExample/Pods-IGListKitTodayExample.release.xcconfig new file mode 100644 index 000000000..76789ae5c --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-IGListKitTodayExample/Pods-IGListKitTodayExample.release.xcconfig @@ -0,0 +1,9 @@ +ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO +FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/IGListKit" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' +OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/IGListKit/IGListKit.framework/Headers" +OTHER_LDFLAGS = $(inherited) -framework "IGListKit" +PODS_BUILD_DIR = $BUILD_DIR +PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT}/Pods diff --git a/IGListKit.xcodeproj/project.pbxproj b/IGListKit.xcodeproj/project.pbxproj index 76c16fcc6..138058e98 100644 --- a/IGListKit.xcodeproj/project.pbxproj +++ b/IGListKit.xcodeproj/project.pbxproj @@ -10,6 +10,10 @@ 01E12EE2D2F55E9DE8928E1E /* Pods_IGListKit_tvOSTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 529C388FDB3DF79737F3496A /* Pods_IGListKit_tvOSTests.framework */; }; 26271C8A1DAE94E40073E116 /* IGTestSingleNibItemDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 26271C891DAE94E40073E116 /* IGTestSingleNibItemDataSource.m */; }; 26271C8C1DAE96740073E116 /* IGListSingleNibItemControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 26271C8B1DAE96740073E116 /* IGListSingleNibItemControllerTests.m */; }; + 290486201DCD02750007F41D /* IGTestNibSupplementaryView.h in Headers */ = {isa = PBXBuildFile; fileRef = 2904861E1DCD02750007F41D /* IGTestNibSupplementaryView.h */; }; + 290486211DCD02750007F41D /* IGTestNibSupplementaryView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2904861F1DCD02750007F41D /* IGTestNibSupplementaryView.m */; }; + 2914BEE91DCD15F400C96401 /* IGTestNibSupplementaryView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2904861C1DCD02140007F41D /* IGTestNibSupplementaryView.xib */; }; + 2914BEEA1DCD15F400C96401 /* IGTestNibSupplementaryView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2904861C1DCD02140007F41D /* IGTestNibSupplementaryView.xib */; }; 296176F71D9D54C100F40F34 /* IGListScrollDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 296176EF1D9D54C100F40F34 /* IGListScrollDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; 296176F81D9D54C100F40F34 /* IGListSectionController.h in Headers */ = {isa = PBXBuildFile; fileRef = 296176F01D9D54C100F40F34 /* IGListSectionController.h */; settings = {ATTRIBUTES = (Public, ); }; }; 296176F91D9D54C100F40F34 /* IGListSectionController.m in Sources */ = {isa = PBXBuildFile; fileRef = 296176F11D9D54C100F40F34 /* IGListSectionController.m */; }; @@ -26,9 +30,15 @@ 5C81083F8E7AEF4B3EBE8871 /* Pods_IGListKitTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FD40284889DE182FFC7F471E /* Pods_IGListKitTests.framework */; }; 821BC4C01DB8C9D500172ED0 /* IGListSingleStoryboardItemControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 821BC4BE1DB8C95300172ED0 /* IGListSingleStoryboardItemControllerTests.m */; }; 821BC4C41DB8CEF800172ED0 /* IGTestStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 821BC4C21DB8CAE900172ED0 /* IGTestStoryboard.storyboard */; }; - 821BC4CB1DB8D60100172ED0 /* IGTestSingleStoryboardViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 821BC4C81DB8D5B200172ED0 /* IGTestSingleStoryboardViewController.m */; }; + 821BC4CB1DB8D60100172ED0 /* IGTestStoryboardViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 821BC4C81DB8D5B200172ED0 /* IGTestStoryboardViewController.m */; }; 821BC4D01DB8D90900172ED0 /* IGTestStoryboardCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 821BC4CD1DB8D8C500172ED0 /* IGTestStoryboardCell.m */; }; 821BC4D31DB981AB00172ED0 /* IGTestSingleStoryboardItemDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 821BC4D21DB981AB00172ED0 /* IGTestSingleStoryboardItemDataSource.m */; }; + 8240C7F01DC272CA00B3AAE7 /* IGTestStoryboardSupplementaryView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8240C7EF1DC272CA00B3AAE7 /* IGTestStoryboardSupplementaryView.m */; }; + 8240C7F21DC284C300B3AAE7 /* IGListAdapterStoryboardTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8240C7F11DC284C300B3AAE7 /* IGListAdapterStoryboardTests.m */; }; + 8240C7F51DC2D99300B3AAE7 /* IGTestStoryboardSupplementarySource.m in Sources */ = {isa = PBXBuildFile; fileRef = 8240C7F41DC2D99300B3AAE7 /* IGTestStoryboardSupplementarySource.m */; }; + 8240C7F81DC2F3FB00B3AAE7 /* IGListTestStoryboardSection.m in Sources */ = {isa = PBXBuildFile; fileRef = 8240C7F71DC2F3FB00B3AAE7 /* IGListTestStoryboardSection.m */; }; + 8240C7FB1DC2F6CF00B3AAE7 /* IGListTestAdapterStoryboardDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 8240C7FA1DC2F6CF00B3AAE7 /* IGListTestAdapterStoryboardDataSource.m */; }; + 829D7BAA1DD1819000549816 /* IGListSectionMapTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 829D7BA81DD1816400549816 /* IGListSectionMapTests.m */; }; 88144F071D870EDC007C7F66 /* IGListAdapterE2ETests.m in Sources */ = {isa = PBXBuildFile; fileRef = 88144EE21D870EDC007C7F66 /* IGListAdapterE2ETests.m */; }; 88144F081D870EDC007C7F66 /* IGListAdapterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 88144EE31D870EDC007C7F66 /* IGListAdapterTests.m */; }; 88144F091D870EDC007C7F66 /* IGListAdapterUpdaterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 88144EE41D870EDC007C7F66 /* IGListAdapterUpdaterTests.m */; }; @@ -36,7 +46,6 @@ 88144F0B1D870EDC007C7F66 /* IGListDiffSwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88144EE61D870EDC007C7F66 /* IGListDiffSwiftTests.swift */; }; 88144F0C1D870EDC007C7F66 /* IGListDiffTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 88144EE81D870EDC007C7F66 /* IGListDiffTests.m */; }; 88144F0D1D870EDC007C7F66 /* IGListDisplayHandlerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 88144EE91D870EDC007C7F66 /* IGListDisplayHandlerTests.m */; }; - 88144F0F1D870EDC007C7F66 /* IGListObjectMapTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 88144EEC1D870EDC007C7F66 /* IGListObjectMapTests.m */; }; 88144F101D870EDC007C7F66 /* IGListSingleSectionControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 88144EED1D870EDC007C7F66 /* IGListSingleSectionControllerTests.m */; }; 88144F111D870EDC007C7F66 /* IGListStackSectionControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 88144EEE1D870EDC007C7F66 /* IGListStackSectionControllerTests.m */; }; 88144F121D870EDC007C7F66 /* IGListWorkingRangeHandlerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 88144EEF1D870EDC007C7F66 /* IGListWorkingRangeHandlerTests.m */; }; @@ -95,8 +104,6 @@ 88144F8F1D870F3E007C7F66 /* IGListMoveIndexPathInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 88144F521D870F3E007C7F66 /* IGListMoveIndexPathInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; 88144F911D870F3E007C7F66 /* IGListWorkingRangeHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 88144F541D870F3E007C7F66 /* IGListWorkingRangeHandler.h */; settings = {ATTRIBUTES = (Private, ); }; }; 88144F921D870F3E007C7F66 /* IGListWorkingRangeHandler.mm in Sources */ = {isa = PBXBuildFile; fileRef = 88144F551D870F3E007C7F66 /* IGListWorkingRangeHandler.mm */; }; - 88144F931D870F3E007C7F66 /* NSIndexSet+PrettyDescription.h in Headers */ = {isa = PBXBuildFile; fileRef = 88144F561D870F3E007C7F66 /* NSIndexSet+PrettyDescription.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 88144F941D870F3E007C7F66 /* NSIndexSet+PrettyDescription.m in Sources */ = {isa = PBXBuildFile; fileRef = 88144F571D870F3E007C7F66 /* NSIndexSet+PrettyDescription.m */; }; 88144F951D870F3E007C7F66 /* UICollectionView+IGListBatchUpdateData.h in Headers */ = {isa = PBXBuildFile; fileRef = 88144F581D870F3E007C7F66 /* UICollectionView+IGListBatchUpdateData.h */; settings = {ATTRIBUTES = (Private, ); }; }; 88144F961D870F3E007C7F66 /* UICollectionView+IGListBatchUpdateData.m in Sources */ = {isa = PBXBuildFile; fileRef = 88144F591D870F3E007C7F66 /* UICollectionView+IGListBatchUpdateData.m */; }; 88144F971D870F3E007C7F66 /* NSObject+IGListDiffable.h in Headers */ = {isa = PBXBuildFile; fileRef = 88144F5A1D870F3E007C7F66 /* NSObject+IGListDiffable.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -157,12 +164,10 @@ 885FE2201DC51B37009CE2B4 /* IGListSectionMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 296177001D9D54E300F40F34 /* IGListSectionMap.h */; settings = {ATTRIBUTES = (Private, ); }; }; 885FE2211DC51B37009CE2B4 /* IGListStackedSectionControllerInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 296177021D9D54E300F40F34 /* IGListStackedSectionControllerInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; 885FE2221DC51B37009CE2B4 /* IGListWorkingRangeHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 88144F541D870F3E007C7F66 /* IGListWorkingRangeHandler.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 885FE2231DC51B37009CE2B4 /* NSIndexSet+PrettyDescription.h in Headers */ = {isa = PBXBuildFile; fileRef = 88144F561D870F3E007C7F66 /* NSIndexSet+PrettyDescription.h */; settings = {ATTRIBUTES = (Private, ); }; }; 885FE2241DC51B37009CE2B4 /* UICollectionView+IGListBatchUpdateData.h in Headers */ = {isa = PBXBuildFile; fileRef = 88144F581D870F3E007C7F66 /* UICollectionView+IGListBatchUpdateData.h */; settings = {ATTRIBUTES = (Private, ); }; }; 885FE2251DC51B3F009CE2B4 /* IGListAdapterProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 88144F481D870F3E007C7F66 /* IGListAdapterProxy.m */; }; 885FE2261DC51B3F009CE2B4 /* IGListDisplayHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 88144F4B1D870F3E007C7F66 /* IGListDisplayHandler.m */; }; 885FE2271DC51B3F009CE2B4 /* IGListSectionMap.m in Sources */ = {isa = PBXBuildFile; fileRef = 296177011D9D54E300F40F34 /* IGListSectionMap.m */; }; - 885FE2281DC51B3F009CE2B4 /* NSIndexSet+PrettyDescription.m in Sources */ = {isa = PBXBuildFile; fileRef = 88144F571D870F3E007C7F66 /* NSIndexSet+PrettyDescription.m */; }; 885FE2291DC51B3F009CE2B4 /* UICollectionView+IGListBatchUpdateData.m in Sources */ = {isa = PBXBuildFile; fileRef = 88144F591D870F3E007C7F66 /* UICollectionView+IGListBatchUpdateData.m */; }; 885FE22A1DC51B3F009CE2B4 /* IGListWorkingRangeHandler.mm in Sources */ = {isa = PBXBuildFile; fileRef = 88144F551D870F3E007C7F66 /* IGListWorkingRangeHandler.mm */; }; 885FE22B1DC51B76009CE2B4 /* IGListAdapterE2ETests.m in Sources */ = {isa = PBXBuildFile; fileRef = 88144EE21D870EDC007C7F66 /* IGListAdapterE2ETests.m */; }; @@ -172,7 +177,6 @@ 885FE22F1DC51B76009CE2B4 /* IGListDiffSwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88144EE61D870EDC007C7F66 /* IGListDiffSwiftTests.swift */; }; 885FE2301DC51B76009CE2B4 /* IGListDiffTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 88144EE81D870EDC007C7F66 /* IGListDiffTests.m */; }; 885FE2311DC51B76009CE2B4 /* IGListDisplayHandlerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 88144EE91D870EDC007C7F66 /* IGListDisplayHandlerTests.m */; }; - 885FE2321DC51B76009CE2B4 /* IGListObjectMapTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 88144EEC1D870EDC007C7F66 /* IGListObjectMapTests.m */; }; 885FE2331DC51B76009CE2B4 /* IGListSingleSectionControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 88144EED1D870EDC007C7F66 /* IGListSingleSectionControllerTests.m */; }; 885FE2341DC51B76009CE2B4 /* IGListSingleNibItemControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 26271C8B1DAE96740073E116 /* IGListSingleNibItemControllerTests.m */; }; 885FE2351DC51B76009CE2B4 /* IGListSingleStoryboardItemControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 821BC4BE1DB8C95300172ED0 /* IGListSingleStoryboardItemControllerTests.m */; }; @@ -189,7 +193,7 @@ 885FE2401DC51B86009CE2B4 /* IGTestSingleItemDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 88144F021D870EDC007C7F66 /* IGTestSingleItemDataSource.m */; }; 885FE2411DC51B86009CE2B4 /* IGTestSingleNibItemDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 26271C891DAE94E40073E116 /* IGTestSingleNibItemDataSource.m */; }; 885FE2421DC51B86009CE2B4 /* IGTestSingleStoryboardItemDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 821BC4D21DB981AB00172ED0 /* IGTestSingleStoryboardItemDataSource.m */; }; - 885FE2431DC51B86009CE2B4 /* IGTestSingleStoryboardViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 821BC4C81DB8D5B200172ED0 /* IGTestSingleStoryboardViewController.m */; }; + 885FE2431DC51B86009CE2B4 /* IGTestStoryboardViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 821BC4C81DB8D5B200172ED0 /* IGTestStoryboardViewController.m */; }; 885FE2441DC51B86009CE2B4 /* IGTestStackedDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 88144F041D870EDC007C7F66 /* IGTestStackedDataSource.m */; }; 885FE2451DC51B86009CE2B4 /* IGTestStoryboardCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 821BC4CD1DB8D8C500172ED0 /* IGTestStoryboardCell.m */; }; 885FE2461DC51B86009CE2B4 /* IGTestSupplementarySource.m in Sources */ = {isa = PBXBuildFile; fileRef = 88144F061D870EDC007C7F66 /* IGTestSupplementarySource.m */; }; @@ -221,6 +225,9 @@ 26271C881DAE94E40073E116 /* IGTestSingleNibItemDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IGTestSingleNibItemDataSource.h; sourceTree = ""; }; 26271C891DAE94E40073E116 /* IGTestSingleNibItemDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGTestSingleNibItemDataSource.m; sourceTree = ""; }; 26271C8B1DAE96740073E116 /* IGListSingleNibItemControllerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGListSingleNibItemControllerTests.m; sourceTree = ""; }; + 2904861C1DCD02140007F41D /* IGTestNibSupplementaryView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = IGTestNibSupplementaryView.xib; sourceTree = ""; }; + 2904861E1DCD02750007F41D /* IGTestNibSupplementaryView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IGTestNibSupplementaryView.h; sourceTree = ""; }; + 2904861F1DCD02750007F41D /* IGTestNibSupplementaryView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGTestNibSupplementaryView.m; sourceTree = ""; }; 294369B01DB1B7AE0025F6E7 /* IGTestNibCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = IGTestNibCell.xib; sourceTree = ""; }; 296176EF1D9D54C100F40F34 /* IGListScrollDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IGListScrollDelegate.h; sourceTree = ""; }; 296176F01D9D54C100F40F34 /* IGListSectionController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IGListSectionController.h; sourceTree = ""; }; @@ -238,12 +245,22 @@ 6BCA3FF59943AD1DAC2077E3 /* Pods-IGListKitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-IGListKitTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-IGListKitTests/Pods-IGListKitTests.release.xcconfig"; sourceTree = ""; }; 821BC4BE1DB8C95300172ED0 /* IGListSingleStoryboardItemControllerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGListSingleStoryboardItemControllerTests.m; sourceTree = ""; }; 821BC4C21DB8CAE900172ED0 /* IGTestStoryboard.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = IGTestStoryboard.storyboard; sourceTree = ""; }; - 821BC4C71DB8D5B200172ED0 /* IGTestSingleStoryboardViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IGTestSingleStoryboardViewController.h; sourceTree = ""; }; - 821BC4C81DB8D5B200172ED0 /* IGTestSingleStoryboardViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGTestSingleStoryboardViewController.m; sourceTree = ""; }; + 821BC4C71DB8D5B200172ED0 /* IGTestStoryboardViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IGTestStoryboardViewController.h; sourceTree = ""; }; + 821BC4C81DB8D5B200172ED0 /* IGTestStoryboardViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGTestStoryboardViewController.m; sourceTree = ""; }; 821BC4CC1DB8D8C500172ED0 /* IGTestStoryboardCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IGTestStoryboardCell.h; sourceTree = ""; }; 821BC4CD1DB8D8C500172ED0 /* IGTestStoryboardCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGTestStoryboardCell.m; sourceTree = ""; }; 821BC4D11DB9816E00172ED0 /* IGTestSingleStoryboardItemDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IGTestSingleStoryboardItemDataSource.h; sourceTree = ""; }; 821BC4D21DB981AB00172ED0 /* IGTestSingleStoryboardItemDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGTestSingleStoryboardItemDataSource.m; sourceTree = ""; }; + 8240C7EE1DC272CA00B3AAE7 /* IGTestStoryboardSupplementaryView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IGTestStoryboardSupplementaryView.h; sourceTree = ""; }; + 8240C7EF1DC272CA00B3AAE7 /* IGTestStoryboardSupplementaryView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGTestStoryboardSupplementaryView.m; sourceTree = ""; }; + 8240C7F11DC284C300B3AAE7 /* IGListAdapterStoryboardTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IGListAdapterStoryboardTests.m; path = Tests/IGListAdapterStoryboardTests.m; sourceTree = SOURCE_ROOT; }; + 8240C7F31DC2D99300B3AAE7 /* IGTestStoryboardSupplementarySource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IGTestStoryboardSupplementarySource.h; sourceTree = ""; }; + 8240C7F41DC2D99300B3AAE7 /* IGTestStoryboardSupplementarySource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGTestStoryboardSupplementarySource.m; sourceTree = ""; }; + 8240C7F61DC2F3FB00B3AAE7 /* IGListTestStoryboardSection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IGListTestStoryboardSection.h; sourceTree = ""; }; + 8240C7F71DC2F3FB00B3AAE7 /* IGListTestStoryboardSection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGListTestStoryboardSection.m; sourceTree = ""; }; + 8240C7F91DC2F6CF00B3AAE7 /* IGListTestAdapterStoryboardDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IGListTestAdapterStoryboardDataSource.h; sourceTree = ""; }; + 8240C7FA1DC2F6CF00B3AAE7 /* IGListTestAdapterStoryboardDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGListTestAdapterStoryboardDataSource.m; sourceTree = ""; }; + 829D7BA81DD1816400549816 /* IGListSectionMapTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGListSectionMapTests.m; sourceTree = ""; }; 841726B542A3E9A4BD48946F /* Pods-IGListKit-tvOSTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-IGListKit-tvOSTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-IGListKit-tvOSTests/Pods-IGListKit-tvOSTests.debug.xcconfig"; sourceTree = ""; }; 88144EE21D870EDC007C7F66 /* IGListAdapterE2ETests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGListAdapterE2ETests.m; sourceTree = ""; }; 88144EE31D870EDC007C7F66 /* IGListAdapterTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGListAdapterTests.m; sourceTree = ""; }; @@ -253,7 +270,6 @@ 88144EE81D870EDC007C7F66 /* IGListDiffTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGListDiffTests.m; sourceTree = ""; }; 88144EE91D870EDC007C7F66 /* IGListDisplayHandlerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGListDisplayHandlerTests.m; sourceTree = ""; }; 88144EEB1D870EDC007C7F66 /* IGListKitTests-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "IGListKitTests-Bridging-Header.h"; sourceTree = ""; }; - 88144EEC1D870EDC007C7F66 /* IGListObjectMapTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGListObjectMapTests.m; sourceTree = ""; }; 88144EED1D870EDC007C7F66 /* IGListSingleSectionControllerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGListSingleSectionControllerTests.m; sourceTree = ""; }; 88144EEE1D870EDC007C7F66 /* IGListStackSectionControllerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGListStackSectionControllerTests.m; sourceTree = ""; }; 88144EEF1D870EDC007C7F66 /* IGListWorkingRangeHandlerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGListWorkingRangeHandlerTests.m; sourceTree = ""; }; @@ -323,8 +339,6 @@ 88144F521D870F3E007C7F66 /* IGListMoveIndexPathInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IGListMoveIndexPathInternal.h; sourceTree = ""; }; 88144F541D870F3E007C7F66 /* IGListWorkingRangeHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IGListWorkingRangeHandler.h; sourceTree = ""; }; 88144F551D870F3E007C7F66 /* IGListWorkingRangeHandler.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = IGListWorkingRangeHandler.mm; sourceTree = ""; }; - 88144F561D870F3E007C7F66 /* NSIndexSet+PrettyDescription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSIndexSet+PrettyDescription.h"; sourceTree = ""; }; - 88144F571D870F3E007C7F66 /* NSIndexSet+PrettyDescription.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSIndexSet+PrettyDescription.m"; sourceTree = ""; }; 88144F581D870F3E007C7F66 /* UICollectionView+IGListBatchUpdateData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UICollectionView+IGListBatchUpdateData.h"; sourceTree = ""; }; 88144F591D870F3E007C7F66 /* UICollectionView+IGListBatchUpdateData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UICollectionView+IGListBatchUpdateData.m"; sourceTree = ""; }; 88144F5A1D870F3E007C7F66 /* NSObject+IGListDiffable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+IGListDiffable.h"; sourceTree = ""; }; @@ -380,6 +394,7 @@ isa = PBXGroup; children = ( 294369B01DB1B7AE0025F6E7 /* IGTestNibCell.xib */, + 2904861C1DCD02140007F41D /* IGTestNibSupplementaryView.xib */, 821BC4C21DB8CAE900172ED0 /* IGTestStoryboard.storyboard */, ); path = Assets; @@ -401,10 +416,14 @@ children = ( 88144EF11D870EDC007C7F66 /* IGListTestAdapterDataSource.h */, 88144EF21D870EDC007C7F66 /* IGListTestAdapterDataSource.m */, + 8240C7F91DC2F6CF00B3AAE7 /* IGListTestAdapterStoryboardDataSource.h */, + 8240C7FA1DC2F6CF00B3AAE7 /* IGListTestAdapterStoryboardDataSource.m */, 88144EF31D870EDC007C7F66 /* IGListTestOffsettingLayout.h */, 88144EF41D870EDC007C7F66 /* IGListTestOffsettingLayout.m */, 88144EF51D870EDC007C7F66 /* IGListTestSection.h */, 88144EF61D870EDC007C7F66 /* IGListTestSection.m */, + 8240C7F61DC2F3FB00B3AAE7 /* IGListTestStoryboardSection.h */, + 8240C7F71DC2F3FB00B3AAE7 /* IGListTestStoryboardSection.m */, 88144EF71D870EDC007C7F66 /* IGListTestUICollectionViewDataSource.h */, 88144EF81D870EDC007C7F66 /* IGListTestUICollectionViewDataSource.m */, 88144EF91D870EDC007C7F66 /* IGTestCell.h */, @@ -413,6 +432,8 @@ 88144EFC1D870EDC007C7F66 /* IGTestDelegateController.m */, 88144EFD1D870EDC007C7F66 /* IGTestDelegateDataSource.h */, 88144EFE1D870EDC007C7F66 /* IGTestDelegateDataSource.m */, + 2904861E1DCD02750007F41D /* IGTestNibSupplementaryView.h */, + 2904861F1DCD02750007F41D /* IGTestNibSupplementaryView.m */, 88144EFF1D870EDC007C7F66 /* IGTestObject.h */, 88144F001D870EDC007C7F66 /* IGTestObject.m */, 88144F011D870EDC007C7F66 /* IGTestSingleItemDataSource.h */, @@ -421,12 +442,16 @@ 26271C891DAE94E40073E116 /* IGTestSingleNibItemDataSource.m */, 821BC4D11DB9816E00172ED0 /* IGTestSingleStoryboardItemDataSource.h */, 821BC4D21DB981AB00172ED0 /* IGTestSingleStoryboardItemDataSource.m */, - 821BC4C71DB8D5B200172ED0 /* IGTestSingleStoryboardViewController.h */, - 821BC4C81DB8D5B200172ED0 /* IGTestSingleStoryboardViewController.m */, 88144F031D870EDC007C7F66 /* IGTestStackedDataSource.h */, 88144F041D870EDC007C7F66 /* IGTestStackedDataSource.m */, 821BC4CC1DB8D8C500172ED0 /* IGTestStoryboardCell.h */, 821BC4CD1DB8D8C500172ED0 /* IGTestStoryboardCell.m */, + 8240C7F31DC2D99300B3AAE7 /* IGTestStoryboardSupplementarySource.h */, + 8240C7F41DC2D99300B3AAE7 /* IGTestStoryboardSupplementarySource.m */, + 8240C7EE1DC272CA00B3AAE7 /* IGTestStoryboardSupplementaryView.h */, + 8240C7EF1DC272CA00B3AAE7 /* IGTestStoryboardSupplementaryView.m */, + 821BC4C71DB8D5B200172ED0 /* IGTestStoryboardViewController.h */, + 821BC4C81DB8D5B200172ED0 /* IGTestStoryboardViewController.m */, 88144F051D870EDC007C7F66 /* IGTestSupplementarySource.h */, 88144F061D870EDC007C7F66 /* IGTestSupplementarySource.m */, ); @@ -452,8 +477,6 @@ 296177021D9D54E300F40F34 /* IGListStackedSectionControllerInternal.h */, 88144F541D870F3E007C7F66 /* IGListWorkingRangeHandler.h */, 88144F551D870F3E007C7F66 /* IGListWorkingRangeHandler.mm */, - 88144F561D870F3E007C7F66 /* NSIndexSet+PrettyDescription.h */, - 88144F571D870F3E007C7F66 /* NSIndexSet+PrettyDescription.m */, 88144F581D870F3E007C7F66 /* UICollectionView+IGListBatchUpdateData.h */, 88144F591D870F3E007C7F66 /* UICollectionView+IGListBatchUpdateData.m */, ); @@ -540,16 +563,17 @@ 294369AF1DB1B7AE0025F6E7 /* Assets */, 88144EE21D870EDC007C7F66 /* IGListAdapterE2ETests.m */, 88144EE31D870EDC007C7F66 /* IGListAdapterTests.m */, + 8240C7F11DC284C300B3AAE7 /* IGListAdapterStoryboardTests.m */, 88144EE41D870EDC007C7F66 /* IGListAdapterUpdaterTests.m */, 88144EE51D870EDC007C7F66 /* IGListBatchUpdateDataTests.m */, 88144EE61D870EDC007C7F66 /* IGListDiffSwiftTests.swift */, 88144EE81D870EDC007C7F66 /* IGListDiffTests.m */, 88144EE91D870EDC007C7F66 /* IGListDisplayHandlerTests.m */, 88144EEB1D870EDC007C7F66 /* IGListKitTests-Bridging-Header.h */, - 88144EEC1D870EDC007C7F66 /* IGListObjectMapTests.m */, 26271C8B1DAE96740073E116 /* IGListSingleNibItemControllerTests.m */, 88144EED1D870EDC007C7F66 /* IGListSingleSectionControllerTests.m */, 821BC4BE1DB8C95300172ED0 /* IGListSingleStoryboardItemControllerTests.m */, + 829D7BA81DD1816400549816 /* IGListSectionMapTests.m */, 88144EEE1D870EDC007C7F66 /* IGListStackSectionControllerTests.m */, 88144EEF1D870EDC007C7F66 /* IGListWorkingRangeHandlerTests.m */, 887D0B571D870E1E009E01F7 /* Info.plist */, @@ -580,7 +604,6 @@ 885FE2221DC51B37009CE2B4 /* IGListWorkingRangeHandler.h in Headers */, 885FE1EC1DC51B18009CE2B4 /* IGListAdapter.h in Headers */, 885FE1F21DC51B18009CE2B4 /* IGListBatchUpdateData.h in Headers */, - 885FE2231DC51B37009CE2B4 /* NSIndexSet+PrettyDescription.h in Headers */, 885FE2171DC51B37009CE2B4 /* IGListAdapterInternal.h in Headers */, 885FE1FE1DC51B18009CE2B4 /* IGListMoveIndexPath.h in Headers */, 885FE1F81DC51B18009CE2B4 /* IGListExperiments.h in Headers */, @@ -635,6 +658,7 @@ 88144F6C1D870F3E007C7F66 /* IGListDisplayDelegate.h in Headers */, 88144F811D870F3E007C7F66 /* IGListUpdatingDelegate.h in Headers */, 88144F6D1D870F3E007C7F66 /* IGListExperiments.h in Headers */, + 290486201DCD02750007F41D /* IGTestNibSupplementaryView.h in Headers */, 88144F5E1D870F3E007C7F66 /* IGListAdapterDataSource.h in Headers */, 88144F621D870F3E007C7F66 /* IGListAdapterUpdaterDelegate.h in Headers */, 88144F971D870F3E007C7F66 /* NSObject+IGListDiffable.h in Headers */, @@ -661,7 +685,6 @@ 296177031D9D54E300F40F34 /* IGListSectionControllerInternal.h in Headers */, 296177061D9D54E300F40F34 /* IGListStackedSectionControllerInternal.h in Headers */, 88144F861D870F3E007C7F66 /* IGListAdapterUpdaterInternal.h in Headers */, - 88144F931D870F3E007C7F66 /* NSIndexSet+PrettyDescription.h in Headers */, 88144F6E1D870F3E007C7F66 /* IGListIndexPathResult.h in Headers */, 88144F6B1D870F3E007C7F66 /* IGListDiffable.h in Headers */, 88144F871D870F3E007C7F66 /* IGListDisplayHandler.h in Headers */, @@ -814,6 +837,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 2914BEEA1DCD15F400C96401 /* IGTestNibSupplementaryView.xib in Resources */, 885FE2471DC51B90009CE2B4 /* IGTestNibCell.xib in Resources */, 885FE2481DC51B90009CE2B4 /* IGTestStoryboard.storyboard in Resources */, ); @@ -830,6 +854,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 2914BEE91DCD15F400C96401 /* IGTestNibSupplementaryView.xib in Resources */, 29EA6C491DB43A8000957A88 /* IGTestNibCell.xib in Resources */, 821BC4C41DB8CEF800172ED0 /* IGTestStoryboard.storyboard in Resources */, ); @@ -936,7 +961,6 @@ buildActionMask = 2147483647; files = ( 885FE2141DC51B21009CE2B4 /* NSObject+IGListDiffable.m in Sources */, - 885FE2281DC51B3F009CE2B4 /* NSIndexSet+PrettyDescription.m in Sources */, 885FE2261DC51B3F009CE2B4 /* IGListDisplayHandler.m in Sources */, 885FE2251DC51B3F009CE2B4 /* IGListAdapterProxy.m in Sources */, 885FE22A1DC51B3F009CE2B4 /* IGListWorkingRangeHandler.mm in Sources */, @@ -980,14 +1004,13 @@ 885FE2421DC51B86009CE2B4 /* IGTestSingleStoryboardItemDataSource.m in Sources */, 885FE2301DC51B76009CE2B4 /* IGListDiffTests.m in Sources */, 885FE22E1DC51B76009CE2B4 /* IGListBatchUpdateDataTests.m in Sources */, - 885FE2321DC51B76009CE2B4 /* IGListObjectMapTests.m in Sources */, 885FE22C1DC51B76009CE2B4 /* IGListAdapterTests.m in Sources */, 885FE22D1DC51B76009CE2B4 /* IGListAdapterUpdaterTests.m in Sources */, 885FE2351DC51B76009CE2B4 /* IGListSingleStoryboardItemControllerTests.m in Sources */, 885FE2411DC51B86009CE2B4 /* IGTestSingleNibItemDataSource.m in Sources */, 885FE2441DC51B86009CE2B4 /* IGTestStackedDataSource.m in Sources */, 885FE2461DC51B86009CE2B4 /* IGTestSupplementarySource.m in Sources */, - 885FE2431DC51B86009CE2B4 /* IGTestSingleStoryboardViewController.m in Sources */, + 885FE2431DC51B86009CE2B4 /* IGTestStoryboardViewController.m in Sources */, 885FE23A1DC51B86009CE2B4 /* IGListTestSection.m in Sources */, 885FE23E1DC51B86009CE2B4 /* IGTestDelegateDataSource.m in Sources */, ); @@ -997,7 +1020,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 88144F941D870F3E007C7F66 /* NSIndexSet+PrettyDescription.m in Sources */, 88144F681D870F3E007C7F66 /* IGListCollectionView.m in Sources */, 88144F851D870F3E007C7F66 /* IGListAdapterProxy.m in Sources */, 88144F961D870F3E007C7F66 /* UICollectionView+IGListBatchUpdateData.m in Sources */, @@ -1011,6 +1033,7 @@ 296176FC1D9D54C100F40F34 /* IGListSingleSectionController.m in Sources */, 296177051D9D54E300F40F34 /* IGListSectionMap.m in Sources */, 88144F771D870F3E007C7F66 /* IGListMoveIndex.m in Sources */, + 290486211DCD02750007F41D /* IGTestNibSupplementaryView.m in Sources */, 88144F921D870F3E007C7F66 /* IGListWorkingRangeHandler.mm in Sources */, 88144F5D1D870F3E007C7F66 /* IGListAdapter.m in Sources */, 88144F611D870F3E007C7F66 /* IGListAdapterUpdater.m in Sources */, @@ -1027,10 +1050,12 @@ 88144F1C1D870EDC007C7F66 /* IGTestStackedDataSource.m in Sources */, 88144F181D870EDC007C7F66 /* IGTestDelegateController.m in Sources */, 88144F0D1D870EDC007C7F66 /* IGListDisplayHandlerTests.m in Sources */, + 8240C7F51DC2D99300B3AAE7 /* IGTestStoryboardSupplementarySource.m in Sources */, 88144F1B1D870EDC007C7F66 /* IGTestSingleItemDataSource.m in Sources */, 88144F171D870EDC007C7F66 /* IGTestCell.m in Sources */, 821BC4C01DB8C9D500172ED0 /* IGListSingleStoryboardItemControllerTests.m in Sources */, 88144F141D870EDC007C7F66 /* IGListTestOffsettingLayout.m in Sources */, + 8240C7FB1DC2F6CF00B3AAE7 /* IGListTestAdapterStoryboardDataSource.m in Sources */, 88144F131D870EDC007C7F66 /* IGListTestAdapterDataSource.m in Sources */, 88144F071D870EDC007C7F66 /* IGListAdapterE2ETests.m in Sources */, 88144F111D870EDC007C7F66 /* IGListStackSectionControllerTests.m in Sources */, @@ -1040,17 +1065,20 @@ 88144F0C1D870EDC007C7F66 /* IGListDiffTests.m in Sources */, 88144F0A1D870EDC007C7F66 /* IGListBatchUpdateDataTests.m in Sources */, 26271C8C1DAE96740073E116 /* IGListSingleNibItemControllerTests.m in Sources */, + 829D7BAA1DD1819000549816 /* IGListSectionMapTests.m in Sources */, 88144F101D870EDC007C7F66 /* IGListSingleSectionControllerTests.m in Sources */, 88144F121D870EDC007C7F66 /* IGListWorkingRangeHandlerTests.m in Sources */, 821BC4D31DB981AB00172ED0 /* IGTestSingleStoryboardItemDataSource.m in Sources */, 88144F151D870EDC007C7F66 /* IGListTestSection.m in Sources */, 88144F1D1D870EDC007C7F66 /* IGTestSupplementarySource.m in Sources */, 88144F081D870EDC007C7F66 /* IGListAdapterTests.m in Sources */, - 821BC4CB1DB8D60100172ED0 /* IGTestSingleStoryboardViewController.m in Sources */, + 8240C7F21DC284C300B3AAE7 /* IGListAdapterStoryboardTests.m in Sources */, + 8240C7F01DC272CA00B3AAE7 /* IGTestStoryboardSupplementaryView.m in Sources */, + 821BC4CB1DB8D60100172ED0 /* IGTestStoryboardViewController.m in Sources */, 821BC4D01DB8D90900172ED0 /* IGTestStoryboardCell.m in Sources */, 88144F161D870EDC007C7F66 /* IGListTestUICollectionViewDataSource.m in Sources */, 88144F091D870EDC007C7F66 /* IGListAdapterUpdaterTests.m in Sources */, - 88144F0F1D870EDC007C7F66 /* IGListObjectMapTests.m in Sources */, + 8240C7F81DC2F3FB00B3AAE7 /* IGListTestStoryboardSection.m in Sources */, 26271C8A1DAE94E40073E116 /* IGTestSingleNibItemDataSource.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Source/IGListAdapter.h b/Source/IGListAdapter.h index 5e4f76c39..0b67be7ed 100644 --- a/Source/IGListAdapter.h +++ b/Source/IGListAdapter.h @@ -23,14 +23,19 @@ NS_ASSUME_NONNULL_BEGIN +/** + A block to execute when list updates completes. + + @param finished Specifies whether or not the updates finished. + */ typedef void (^IGListUpdaterCompletion)(BOOL finished); /** - IGListAdapter objects provide an abstraction for feeds of objects in a UICollectionView by breaking each object into - individual sections, called "section controllers". These controllers (objects conforming to IGListSectionType) act as a + `IGListAdapter` objects provide an abstraction for feeds of objects in a `UICollectionView` by breaking each object into + individual sections, called "section controllers". These controllers (objects conforming to `IGListSectionType`) act as a data source and delegate for each section. - Feed implementations must act as the data source for an IGListAdapter in order to drive the objects and section + Feed implementations must act as the data source for an `IGListAdapter` in order to drive the objects and section controllers in a collection view. */ IGLK_SUBCLASSING_RESTRICTED @@ -57,14 +62,14 @@ IGLK_SUBCLASSING_RESTRICTED @property (nonatomic, nullable, weak) id delegate; /** - The object that receives UICollectionViewDelegate events. + The object that receives `UICollectionViewDelegate` events. - @discussion This object /will not/ receive UIScrollViewDelegate events. Instead use scrollViewDelegate. + @note This object *will not* receive `UIScrollViewDelegate` events. Instead use scrollViewDelegate. */ @property (nonatomic, nullable, weak) id collectionViewDelegate; /** - The object that receives UIScrollViewDelegate events. + The object that receives `UIScrollViewDelegate` events. */ @property (nonatomic, nullable, weak) id scrollViewDelegate; @@ -74,20 +79,20 @@ IGLK_SUBCLASSING_RESTRICTED @property (nonatomic, assign) IGListExperiment experiments; /** - Initialize a new IGListAdapter object with a collection view, data source, and updating delegate. + Initializes a new `IGListAdapter` object. - @param updatingDelegate An object that manages updates to the UICollectionView. + @param updatingDelegate An object that manages updates to the collection view. @param viewController The view controller that will house the adapter. @param workingRangeSize The number of objects before and after the viewport to consider within the working range. - @return A new IGListAdapter object. + @return A new list adapter object. - @discussion The working range is the number of objects beyond the visible objects (plus and minus) that should be + @note The working range is the number of objects beyond the visible objects (plus and minus) that should be notified when they are close to being visible. For instance, if you have 3 objects on screen and a working range of 2, the previous and succeeding 2 objects will be notified that they are within the working range. As you scroll the list the range is updated as objects enter and exit the working range. - To opt out of using the working range, you can provide a value of 0. + To opt out of using the working range, you can provide a value of `0`. */ - (instancetype)initWithUpdater:(id )updatingDelegate viewController:(nullable UIViewController *)viewController @@ -95,22 +100,22 @@ IGLK_SUBCLASSING_RESTRICTED /** Perform an update from the previous state of the data source. This is analagous to calling - -[UICollectionView performBatchUpdates:completion:]. + `-[UICollectionView performBatchUpdates:completion:]`. @param animated A flag indicating if the transition should be animated. - @param completion A block executed when the update completes. + @param completion The block to execute when the update completes. */ - (void)performUpdatesAnimated:(BOOL)animated completion:(nullable IGListUpdaterCompletion)completion; /** Perform an immediate reload of the data in the data source, discarding the old objects. - @param completion A block executed when the reload completes. + @param completion The block to execute when the reload completes. */ - (void)reloadDataWithCompletion:(nullable IGListUpdaterCompletion)completion; /** - Reload the infra for specific objects only. + Reload the list for only the specified objects. @param objects The objects to reload. */ @@ -121,41 +126,41 @@ IGLK_SUBCLASSING_RESTRICTED @param sectionController A list object. - @return The section index of the list or NSNotFound. + @return The section index of the list if it exists, otherwise `NSNotFound`. */ - (NSUInteger)sectionForSectionController:(IGListSectionController *)sectionController; /** - Fetch an section controller for an object in the feed. Constant time lookup. + Returns the section controller for the specified object. Constant time lookup. @param object An object from the data source. - @return An section controller or nil. + @return An section controller or `nil` if `object` is not in the list. - @see -[IGListAdapterDataSource listAdapter:sectionControllerForObject:] + @see `-[IGListAdapterDataSource listAdapter:sectionControllerForObject:]` */ - (__kindof IGListSectionController * _Nullable)sectionControllerForObject:(id)object; /** - Fetch the object corresponding to a section in the feed. Constant time lookup. + Returns the object corresponding to a section in the list. Constant time lookup. - @param section A section in the feed. + @param section A section in the list. - @return An object or nil. + @return The object for the specified section, or `nil` if the section does not exist. */ - (nullable id)objectAtSection:(NSUInteger)section; /** - Fetch the section corresponding to an object in the feed. Constant time lookup. + Returns the section corresponding to the specified object in the list. Constant time lookup. - @param object An object in the feed + @param object An object in the list. - @return A section index if found or NSNotFound. + @return The section index of `object` if found, otherwise `NSNotFound`. */ - (NSUInteger)sectionForObject:(id)object; /** - A copy of all the objects currently powering the adapter. + Returns a copy of all the objects currently powering the adapter. @return An array of objects. */ @@ -169,9 +174,16 @@ IGLK_SUBCLASSING_RESTRICTED - (NSArray *> *)visibleSectionControllers; /** - Scroll to an object in the list adapter. + An unordered array of the currently visible objects. + + @return An array of objects + */ +- (NSArray *)visibleObjects; + +/** + Scrolls to the sepcified object in the list adapter. - @param object The object to scroll to. + @param object The object to which to scroll. @param supplementaryKinds The types of supplementary views in the section. @param scrollDirection A flag indicating the direction to scroll. @param animated A flag indicating if the transition should be animated. @@ -182,7 +194,7 @@ IGLK_SUBCLASSING_RESTRICTED animated:(BOOL)animated; /** - Query the size of a cell at the specified index path. + Returns the size of a cell at the specified index path. @param indexPath The index path of the cell. @@ -191,7 +203,7 @@ IGLK_SUBCLASSING_RESTRICTED - (CGSize)sizeForItemAtIndexPath:(NSIndexPath *)indexPath; /** - Query the size of a supplementary view in the list at the specified index path. + Returns the size of a supplementary view in the list at the specified index path. @param elementKind The kind of supplementary view. @param indexPath The index path of the supplementary view. @@ -201,7 +213,14 @@ IGLK_SUBCLASSING_RESTRICTED - (CGSize)sizeForSupplementaryViewOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath; +/** + :nodoc: + */ - (instancetype)init NS_UNAVAILABLE; + +/** + :nodoc: + */ + (instancetype)new NS_UNAVAILABLE; @end diff --git a/Source/IGListAdapter.m b/Source/IGListAdapter.m index 34a706b99..650d596a9 100644 --- a/Source/IGListAdapter.m +++ b/Source/IGListAdapter.m @@ -15,7 +15,6 @@ #import #import "IGListSectionControllerInternal.h" -#import "NSIndexSet+PrettyDescription.h" @implementation IGListAdapter { NSMapTable *> *_cellSectionControllerMap; @@ -74,6 +73,7 @@ - (void)setCollectionView:(IGListCollectionView *)collectionView { _registeredCellClasses = [NSMutableSet new]; _registeredNibNames = [NSMutableSet new]; _registeredSupplementaryViewIdentifiers = [NSMutableSet new]; + _registeredSupplementaryViewNibNames = [NSMutableSet new]; _collectionView = collectionView; _collectionView.dataSource = self; @@ -114,10 +114,6 @@ - (void)setScrollViewDelegate:(id)scrollViewDelegate { - (void)updateAfterPublicSettingsChange { if (_collectionView != nil && _dataSource != nil) { [self updateObjects:[[_dataSource objectsForListAdapter:self] copy]]; - - if (IGListExperimentEnabled(self.experiments, IGListExperimentUICVReloadedInSetter)) { - [_collectionView reloadData]; - } } } @@ -346,6 +342,25 @@ - (NSArray *)objects { return [visibleSectionControllers allObjects]; } +- (NSArray *)visibleObjects { + IGAssertMainThread(); + NSArray *visibleCells = [self.collectionView visibleCells]; + NSMutableSet *visibleObjects = [NSMutableSet new]; + for (UICollectionViewCell *cell in visibleCells) { + IGListSectionController *sectionController = [self sectionControllerForCell:cell]; + IGAssert(sectionController != nil, @"Section controller nil for cell %@", cell); + if (sectionController != nil) { + const NSUInteger section = [self sectionForSectionController:sectionController]; + id object = [self objectAtSection:section]; + IGAssert(object != nil, @"Object not found for section controller %@ at section %zi", sectionController, section); + if (object != nil) { + [visibleObjects addObject:object]; + } + } + } + return [visibleObjects allObjects]; +} + #pragma mark - Layout @@ -710,7 +725,7 @@ - (void)deselectItemAtIndex:(NSInteger)index } - (__kindof UICollectionViewCell *)dequeueReusableCellOfClass:(Class)cellClass - forSectionController:(IGListSectionController *)sectionController + forSectionController:(IGListSectionController *)sectionController atIndex:(NSInteger)index { IGAssertMainThread(); IGParameterAssert(sectionController != nil); @@ -744,7 +759,7 @@ - (UICollectionViewCell *)dequeueReusableCellWithNibName:(NSString *)nibName forSectionController:(IGListSectionController *)sectionController atIndex:(NSInteger)index { IGAssertMainThread(); - IGParameterAssert(nibName != nil); + IGParameterAssert([nibName length] > 0); IGParameterAssert(sectionController != nil); IGParameterAssert(index >= 0); UICollectionView *collectionView = self.collectionView; @@ -759,7 +774,7 @@ - (UICollectionViewCell *)dequeueReusableCellWithNibName:(NSString *)nibName } - (__kindof UICollectionReusableView *)dequeueReusableSupplementaryViewOfKind:(NSString *)elementKind - forSectionController:(IGListSectionController *)sectionController + forSectionController:(IGListSectionController *)sectionController class:(Class)viewClass atIndex:(NSInteger)index { IGAssertMainThread(); @@ -778,6 +793,40 @@ - (__kindof UICollectionReusableView *)dequeueReusableSupplementaryViewOfKind:(N return [collectionView dequeueReusableSupplementaryViewOfKind:elementKind withReuseIdentifier:identifier forIndexPath:indexPath]; } +- (__kindof UICollectionReusableView *)dequeueReusableSupplementaryViewFromStoryboardOfKind:(NSString *)elementKind + withIdentifier:(NSString *)identifier + forSectionController:(IGListSectionController *)sectionController + atIndex:(NSInteger)index { + IGAssertMainThread(); + IGParameterAssert(elementKind.length > 0); + IGParameterAssert(identifier.length > 0); + IGParameterAssert(sectionController != nil); + IGParameterAssert(index >= 0); + UICollectionView *collectionView = self.collectionView; + IGAssert(collectionView != nil, @"Dequeueing Supplementary View from storyboard of kind %@ with identifier %@ for section controller %@ without a collection view at index %zi", elementKind, identifier, sectionController, index); + NSIndexPath *indexPath = [self indexPathForSectionController:sectionController index:index]; + return [collectionView dequeueReusableSupplementaryViewOfKind:elementKind withReuseIdentifier:identifier forIndexPath:indexPath]; +} + +- (__kindof UICollectionReusableView *)dequeueReusableSupplementaryViewOfKind:(NSString *)elementKind + forSectionController:(IGListSectionController *)sectionController + nibName:(NSString *)nibName + bundle:(NSBundle *)bundle + atIndex:(NSInteger)index { + IGAssertMainThread(); + IGParameterAssert([nibName length] > 0); + IGParameterAssert([elementKind length] > 0); + UICollectionView *collectionView = self.collectionView; + IGAssert(collectionView != nil, @"Reloading adapter without a collection view."); + NSIndexPath *indexPath = [self indexPathForSectionController:sectionController index:index]; + if (![self.registeredSupplementaryViewNibNames containsObject:nibName]) { + [self.registeredSupplementaryViewNibNames addObject:nibName]; + UINib *nib = [UINib nibWithNibName:nibName bundle:bundle]; + [collectionView registerNib:nib forSupplementaryViewOfKind:elementKind withReuseIdentifier:nibName]; + } + return [collectionView dequeueReusableSupplementaryViewOfKind:elementKind withReuseIdentifier:nibName forIndexPath:indexPath]; +} + - (void)reloadInSectionController:(IGListSectionController *)sectionController atIndexes:(NSIndexSet *)indexes { IGAssertMainThread(); IGParameterAssert(indexes != nil); diff --git a/Source/IGListAdapterDataSource.h b/Source/IGListAdapterDataSource.h index c28207bdc..f45ca43eb 100644 --- a/Source/IGListAdapterDataSource.h +++ b/Source/IGListAdapterDataSource.h @@ -19,45 +19,45 @@ NS_ASSUME_NONNULL_BEGIN /** - Implement this protocol to provide data to power an IGListAdapter feed. + Implement this protocol to provide data to an `IGListAdapter`. */ @protocol IGListAdapterDataSource /** - Asks the data source for an array of objects for each list in your feed. + Asks the data source for the objects to display in the list. @param listAdapter The list adapter requesting this information. - @return An array of objects for the feed. + @return An array of objects for the list. */ - (NSArray> *)objectsForListAdapter:(IGListAdapter *)listAdapter; /** - Asks the data source for a section controller for the specified data object. + Asks the data source for a section controller for the specified object in the list. @param listAdapter The list adapter requesting this information. - @param object An object in the feed, provided in -objectsForListAdapter:. + @param object An object in the list. - @return An IGListSectionType conforming object that can be displayed in the feed. + @return A new section controller instance that can be displayed in the list. - @discussion New section controllers should be initialized here for objects when asked. You may pass any other data to + @note New section controllers should be initialized here for objects when asked. You may pass any other data to the section controller at this time. - Section controllers are initialized for all objects whenever the IGListAdapter is created, updated, or reloaded. - Section controllers are reused when objects are moved or updated. Maintaining the -[IGListDiffable diffIdentifier] - gauruntees this. + Section controllers are initialized for all objects whenever the `IGListAdapter` is created, updated, or reloaded. + Section controllers are reused when objects are moved or updated. Maintaining the `-[IGListDiffable diffIdentifier]` + guarentees this. */ - (IGListSectionController *)listAdapter:(IGListAdapter *)listAdapter sectionControllerForObject:(id)object; /** - Asks the data source for a view to use as the collection view background when there are no objects. + Asks the data source for a view to use as the collection view background when the list is empty. @param listAdapter The list adapter requesting this information. - @return A view to use as the collection view background, or nil if you don't want a background view. + @return A view to use as the collection view background, or `nil` if you don't want a background view. - @discussion This method is called every time the list adapter is updated. You are free to return new views every time, - but for performance reasons you may want to retain your own view and return it here. The infra is only responsible for + @note This method is called every time the list adapter is updated. You are free to return new views every time, + but for performance reasons you may want to retain the view and return it here. The infra is only responsible for adding the background view and maintaining its visibility. */ - (nullable UIView *)emptyViewForListAdapter:(IGListAdapter *)listAdapter; diff --git a/Source/IGListAdapterDelegate.h b/Source/IGListAdapterDelegate.h index 5531b14c1..9eebe2950 100644 --- a/Source/IGListAdapterDelegate.h +++ b/Source/IGListAdapterDelegate.h @@ -14,7 +14,7 @@ @protocol IGListAdapterDelegate /** - Notifies the delegate that a list object is about to be displayed + Notifies the delegate that a list object is about to be displayed. @param listAdapter The list adapter sending this information. @param object The object that will display. @@ -23,11 +23,11 @@ - (void)listAdapter:(IGListAdapter *)listAdapter willDisplayObject:(id)object atIndex:(NSInteger)index; /** - Notifies the delegate that a list item is no longer being displayed + Notifies the delegate that a list object is no longer being displayed. @param listAdapter The list adapter sending this information. @param object The object that ended display. - @param index The index of the item/object in the list. + @param index The index of the object in the list. */ - (void)listAdapter:(IGListAdapter *)listAdapter didEndDisplayingObject:(id)object atIndex:(NSInteger)index; diff --git a/Source/IGListAdapterUpdater.h b/Source/IGListAdapterUpdater.h index 136d29ca2..8ed2a7e6a 100644 --- a/Source/IGListAdapterUpdater.h +++ b/Source/IGListAdapterUpdater.h @@ -17,22 +17,23 @@ NS_ASSUME_NONNULL_BEGIN /** - This is an out-of-box upater for IGListAdapters. It conforms to IGListUpdatingDelegate and does re-entrant, coalesced - updating on a UICollectionView. + An `IGListAdapterUpdater` is a concrete type that conforms to `IGListUpdatingDelegate`. + It is an out-of-box upater for `IGListAdapter` objects to use. - It also uses IGDiffKit (a least-minimal diff) for calculating UI updates when IGListAdapter calls - -performUpdateWithCollectionView:fromObjects:toObjects:completion:. + @note This updater performs re-entrant, coalesced updating for a list. It also uses a least-minimal diff + for calculating UI updates when `IGListAdapter` calls + `-performUpdateWithCollectionView:fromObjects:toObjects:completion:`. */ IGLK_SUBCLASSING_RESTRICTED @interface IGListAdapterUpdater : NSObject /** - A delegate that receives events with data on the performance of a transition. + The delegate that receives events with data on the performance of a transition. */ @property (nonatomic, weak) id delegate; /** - A flag indicating if a move should be treated as a delete+insert. + A flag indicating if a move should be treated as a "delete, then insert" operation. */ @property (nonatomic, assign) BOOL movesAsDeletesInserts; diff --git a/Source/IGListAdapterUpdater.m b/Source/IGListAdapterUpdater.m index 699b51234..06316d23a 100644 --- a/Source/IGListAdapterUpdater.m +++ b/Source/IGListAdapterUpdater.m @@ -208,17 +208,6 @@ - (void)performBatchUpdatesWithCollectionView:(UICollectionView *)collectionView @try { [delegate listAdapterUpdater:self willPerformBatchUpdatesWithCollectionView:collectionView]; - - if (IGListExperimentEnabled(self.experiments, IGListExperimentLayoutBeforeUpdate)) { - /** - There are traces where UICollectionView throws "Invalid update: invalid number of items in section i..." where - logs show that the problem section has a different "before" item count than the assert claims. Our hunch is - that there is some state corruption from too many unanimated updates happening rapidly and layout state - becoming out of sync. - */ - [collectionView layoutIfNeeded]; - } - if (animated) { [collectionView performBatchUpdates:updateBlock completion:completionBlock]; } else { @@ -232,17 +221,6 @@ - (void)performBatchUpdatesWithCollectionView:(UICollectionView *)collectionView } } -- (NSSet *)filterIndexPaths:(NSSet *)indexPaths removingSections:(NSIndexSet *)sections { - NSMutableSet *filteredIndexPaths = [indexPaths mutableCopy]; - for (NSIndexPath *indexPath in indexPaths) { - const NSUInteger section = indexPath.section; - if ([sections containsIndex:section]) { - [filteredIndexPaths removeObject:indexPath]; - } - } - return filteredIndexPaths; -} - void convertReloadToDeleteInsert(NSMutableIndexSet *reloads, NSMutableIndexSet *deletes, NSMutableIndexSet *inserts, @@ -311,16 +289,6 @@ - (void)endPerformBatchUpdates { self.batchUpdateOrReloadInProgress = NO; } -- (NSArray *)trimmedIndexPaths:(NSArray *)indexPaths inSections:(NSIndexSet *)sections { - NSMutableArray *paths = [indexPaths mutableCopy]; - for (NSInteger i = 0; i < paths.count; i++) { - if ([sections containsIndex:[paths[i] section]]) { - [paths removeObjectAtIndex:i]; - } - } - return paths; -} - - (void)cleanupState { self.queuedUpdateIsAnimated = YES; diff --git a/Source/IGListAdapterUpdaterDelegate.h b/Source/IGListAdapterUpdaterDelegate.h index e27228d1e..044493278 100644 --- a/Source/IGListAdapterUpdaterDelegate.h +++ b/Source/IGListAdapterUpdaterDelegate.h @@ -16,12 +16,12 @@ NS_ASSUME_NONNULL_BEGIN /** - A protocol that receives events about IGListAdapterUpdater operations. + A protocol that receives events about `IGListAdapterUpdater` operations. */ @protocol IGListAdapterUpdaterDelegate /** - Notifies the delegate that the updater will call -[UICollectionView performBatchUpdates:completion:]. + Notifies the delegate that the updater will call `-[UICollectionView performBatchUpdates:completion:]`. @param listAdapterUpdater The adapter updater owning the transition. @param collectionView The collection view that will perform the batch updates. @@ -29,62 +29,62 @@ NS_ASSUME_NONNULL_BEGIN - (void)listAdapterUpdater:(IGListAdapterUpdater *)listAdapterUpdater willPerformBatchUpdatesWithCollectionView:(UICollectionView *)collectionView; /** - Notifies the delegate that the updater succesfully finished -[UICollectionView performBatchUpdates:completion:]. + Notifies the delegate that the updater succesfully finished `-[UICollectionView performBatchUpdates:completion:]`. @param listAdapterUpdater The adapter updater owning the transition. @param updates The batch updates that were applied to the collection view. @param collectionView The collection view that performed the batch updates. - @discussion This event is called in the completion block of the batch update. + @note This event is called in the completion block of the batch update. */ - (void)listAdapterUpdater:(IGListAdapterUpdater *)listAdapterUpdater didPerformBatchUpdates:(IGListBatchUpdateData *)updates withCollectionView:(UICollectionView *)collectionView; /** - Notifies the delegate that the updater will call -[UICollectionView insertItemsAtIndexPaths:]. + Notifies the delegate that the updater will call `-[UICollectionView insertItemsAtIndexPaths:]`. @param listAdapterUpdater The adapter updater owning the transition. @param indexPaths An array of index paths that will be inserted. @param collectionView The collection view that will perform the insert. - @discussion This event is only sent when outside of -[UICollectionView performBatchUpdates:completion:]. + @note This event is only sent when outside of `-[UICollectionView performBatchUpdates:completion:]`. */ - (void)listAdapterUpdater:(IGListAdapterUpdater *)listAdapterUpdater willInsertIndexPaths:(NSArray *)indexPaths collectionView:(UICollectionView *)collectionView; /** - Notifies the delegate that the updater will call -[UICollectionView deleteItemsAtIndexPaths:]. + Notifies the delegate that the updater will call `-[UICollectionView deleteItemsAtIndexPaths:]`. @param listAdapterUpdater The adapter updater owning the transition. @param indexPaths An array of index paths that will be deleted. @param collectionView The collection view that will perform the delete. - @discussion This event is only sent when outside of -[UICollectionView performBatchUpdates:completion:]. + @note This event is only sent when outside of `-[UICollectionView performBatchUpdates:completion:]`. */ - (void)listAdapterUpdater:(IGListAdapterUpdater *)listAdapterUpdater willDeleteIndexPaths:(NSArray *)indexPaths collectionView:(UICollectionView *)collectionView; /** - Notifies the delegate that the updater will call -[UICollectionView reloadItemsAtIndexPaths:]. + Notifies the delegate that the updater will call `-[UICollectionView reloadItemsAtIndexPaths:]`. @param listAdapterUpdater The adapter updater owning the transition. @param indexPaths An array of index paths that will be reloaded. @param collectionView The collection view that will perform the reload. - @discussion This event is only sent when outside of -[UICollectionView performBatchUpdates:completion:]. + @note This event is only sent when outside of `-[UICollectionView performBatchUpdates:completion:]`. */ - (void)listAdapterUpdater:(IGListAdapterUpdater *)listAdapterUpdater willReloadIndexPaths:(NSArray *)indexPaths collectionView:(UICollectionView *)collectionView; /** - Notifies the delegate that the updater will call -[UICollectionView reloadSections:]. + Notifies the delegate that the updater will call `-[UICollectionView reloadSections:]`. @param listAdapterUpdater The adapter updater owning the transition. @param sections The sections that will be reloaded @param collectionView The collection view that will perform the reload. - @discussion This event is only sent when outside of -[UICollectionView performBatchUpdates:completion:]. + @note This event is only sent when outside of `-[UICollectionView performBatchUpdates:completion:]`. */ - (void)listAdapterUpdater:(IGListAdapterUpdater *)listAdapterUpdater willReloadSections:(NSIndexSet *)sections collectionView:(UICollectionView *)collectionView; /** - Notifies the delegate that the updater will call -[UICollectionView reloadData]. + Notifies the delegate that the updater will call `-[UICollectionView reloadData]`. @param listAdapterUpdater The adapter updater owning the transition. @param collectionView The collection view that will be reloaded. @@ -92,7 +92,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)listAdapterUpdater:(IGListAdapterUpdater *)listAdapterUpdater willReloadDataWithCollectionView:(UICollectionView *)collectionView; /** - Notifies the delegate that the updater successfully called -[UICollectionView reloadData]. + Notifies the delegate that the updater successfully called `-[UICollectionView reloadData]`. @param listAdapterUpdater The adapter updater owning the transition. @param collectionView The collection view that reloaded. @@ -100,7 +100,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)listAdapterUpdater:(IGListAdapterUpdater *)listAdapterUpdater didReloadDataWithCollectionView:(UICollectionView *)collectionView; /** - Notifies the delegate that the collection view threw an exception in -[UICollectionView performBatchUpdates:completion:]. + Notifies the delegate that the collection view threw an exception in `-[UICollectionView performBatchUpdates:completion:]`. @param listAdapterUpdater The adapter updater owning the transition. @param exception The exception thrown by the collection view. diff --git a/Source/IGListAssert.h b/Source/IGListAssert.h index 361947398..2781e0e9a 100644 --- a/Source/IGListAssert.h +++ b/Source/IGListAssert.h @@ -9,12 +9,12 @@ #ifndef IGAssert #define IGAssert( condition, ... ) NSCAssert( (condition) , ##__VA_ARGS__) -#endif // #ifndef IGAssert +#endif // IGAssert #ifndef IGParameterAssert #define IGParameterAssert( condition ) IGAssert( (condition) , @"Invalid parameter not satisfying: %@", @#condition) -#endif // #ifndef IGParameterAssert +#endif // IGParameterAssert #ifndef IGAssertMainThread #define IGAssertMainThread() IGAssert( ([NSThread isMainThread] == YES), @"Must be on the main thread") -#endif // #ifndef IGAssertMainThread +#endif // IGAssertMainThread diff --git a/Source/IGListBatchUpdateData.h b/Source/IGListBatchUpdateData.h index 88b2324dc..7b6675b88 100644 --- a/Source/IGListBatchUpdateData.h +++ b/Source/IGListBatchUpdateData.h @@ -15,44 +15,45 @@ NS_ASSUME_NONNULL_BEGIN /** - This object takes section indexes and item index paths and performs cleanup on init in order to perform a crash-free - update via -[UICollectionView performBatchUpdates:completion:]. + An instance of `IGListBatchUpdateData` takes section indexes and item index paths + and performs cleanup on init in order to perform a crash-free + update via `-[UICollectionView performBatchUpdates:completion:]`. */ IGLK_SUBCLASSING_RESTRICTED @interface IGListBatchUpdateData : NSObject /** - Clean section insert indexes. + Section insert indexes. */ @property (nonatomic, strong, readonly) NSIndexSet *insertSections; /** - Clean section delete indexes. + Section delete indexes. */ @property (nonatomic, strong, readonly) NSIndexSet *deleteSections; /** - Clean section moves. + section moves. */ @property (nonatomic, strong, readonly) NSSet *moveSections; /** - Clean item insert index paths. + Item insert index paths. */ @property (nonatomic, strong, readonly) NSSet *insertIndexPaths; /** - Clean item delete index paths. + Item delete index paths. */ @property (nonatomic, strong, readonly) NSSet *deleteIndexPaths; /** - Clean item reload index paths. + Item reload index paths. */ @property (nonatomic, strong, readonly) NSSet *reloadIndexPaths; /** - Create a new batch update object with section and item operations. + Creates a new batch update object with section and item operations. @param insertSections Section indexes to insert. @param deleteSections Section indexes to delete. @@ -61,7 +62,7 @@ IGLK_SUBCLASSING_RESTRICTED @param deleteIndexPaths Item index paths to delete. @param reloadIndexPaths Item index paths to reload. - @return A new batch update object with cleaned update operations. + @return A new batch update object. */ - (instancetype)initWithInsertSections:(NSIndexSet *)insertSections deleteSections:(NSIndexSet *)deleteSections @@ -70,7 +71,14 @@ IGLK_SUBCLASSING_RESTRICTED deleteIndexPaths:(NSSet *)deleteIndexPaths reloadIndexPaths:(NSSet *)reloadIndexPaths NS_DESIGNATED_INITIALIZER; +/** + :nodoc: + */ - (instancetype)init NS_UNAVAILABLE; + +/** + :nodoc: + */ + (instancetype)new NS_UNAVAILABLE; @end diff --git a/Source/IGListBatchUpdateData.mm b/Source/IGListBatchUpdateData.mm index f2c5fe32e..bd402015e 100644 --- a/Source/IGListBatchUpdateData.mm +++ b/Source/IGListBatchUpdateData.mm @@ -40,21 +40,6 @@ static void convertMoveToDeleteAndInsert(NSMutableSet *moves, @implementation IGListBatchUpdateData -// Converts all moves that have section operations into a section delete + insert. -+ (void)cleanIndexSetWithMap:(const std::unordered_map &)map - moves:(NSMutableSet *)moves - sections:(NSMutableIndexSet *)sections - deletes:(NSMutableIndexSet *)deletes - inserts:(NSMutableIndexSet *)inserts { - for(const auto &i : map) { - const NSUInteger index = i.first; - if ([sections containsIndex:index]) { - [sections removeIndex:index]; - convertMoveToDeleteAndInsert(moves, i.second, deletes, inserts); - } - } -} - // Converts all section moves that have index path operations into a section delete + insert. + (void)cleanIndexPathsWithMap:(const std::unordered_map &)map moves:(NSMutableSet *)moves diff --git a/Source/IGListCollectionContext.h b/Source/IGListCollectionContext.h index 28ba5dc80..262b21bda 100644 --- a/Source/IGListCollectionContext.h +++ b/Source/IGListCollectionContext.h @@ -15,40 +15,42 @@ NS_ASSUME_NONNULL_BEGIN @protocol IGListSectionType; /** - The collection context provides limited access to the collection related information that - section controllers need for things like sizing, dequeing cells, insterting/deleting/reloading, etc. + The collection context provides limited access to the collection-related information that + section controllers need for operations like sizing, dequeing cells, insterting, deleting, reloading, etc. */ @protocol IGListCollectionContext /** - Size of the collection view. Provided primarily for sizing cells. + The size of the collection view. You may use this for sizing cells. */ @property (nonatomic, readonly) CGSize containerSize; /** - Query for the index a cell in the collection relative to the section controller. + Returns the index of the specified cell in the collection relative to the section controller. @param cell An existing cell in the collection. @param sectionController The section controller requesting this information. - @return The index of the cell or NSNotFound if it does not exist in the collection. + @return The index of the cell or `NSNotFound` if it does not exist in the collection. */ - (NSUInteger)indexForCell:(UICollectionViewCell *)cell sectionController:(IGListSectionController *)sectionController; /** - Query for a cell in the collection. May return nil if the cell is offscreen. + Returns the cell in the collection at the specified index for the section controller. @param index The index of the desired cell. @param sectionController The section controller requesting this information. @return The collection view cell, or `nil` if not found. + + @warning This method may return `nil` if the cell is offscreen. */ - (nullable __kindof UICollectionViewCell *)cellForItemAtIndex:(NSInteger)index sectionController:(IGListSectionController *)sectionController; /** - Query for the visible cells for the given section controller. + Returns the visible cells for the given section controller. @param sectionController The section controller requesting this information. @@ -68,22 +70,22 @@ NS_ASSUME_NONNULL_BEGIN animated:(BOOL)animated; /** - Query the section index of an section controller. + Returns the section index of an section controller. @param sectionController An section controller object. - @return The section index of the list if found, otherwise `NSNotFound`. + @return The section index of the controller if found, otherwise `NSNotFound`. */ - (NSUInteger)sectionForSectionController:(IGListSectionController *)sectionController; /** - Dequeues a cell from the UICollectionView reuse pool. + Dequeues a cell from the collection view reuse pool. @param cellClass The class of the cell you want to dequeue. @param sectionController The section controller requesting this information. @param index The index of the cell. - @return A cell dequeued from the reuse pool or newly created. + @return A cell dequeued from the reuse pool or a newly created one. @note This method uses a string representation of the cell class as the identifier. */ @@ -92,14 +94,14 @@ NS_ASSUME_NONNULL_BEGIN atIndex:(NSInteger)index; /** - Dequeues a cell from the UICollectionView reuse pool. + Dequeues a cell from the collection view reuse pool. @param nibName The name of the nib file. - @param bundle The bundle in which to search for the nib file. If nil, this method looks for the nib file in the main bundle. + @param bundle The bundle in which to search for the nib file. If `nil`, this method searches the main bundle. @param sectionController The section controller requesting this information. @param index The index of the cell. - @return A cell dequeued from the reuse pool or newly created. + @return A cell dequeued from the reuse pool or a newly created one. @note This method uses a string representation of the cell class as the identifier. */ @@ -109,29 +111,27 @@ NS_ASSUME_NONNULL_BEGIN atIndex:(NSInteger)index; /** - Dequeues a storyboard prototype cell from the UICollectionView reuse pool. + Dequeues a storyboard prototype cell from the collection view reuse pool. @param identifier The identifier of the cell prototype in storyboard. @param sectionController The section controller requesting this information. @param index The index of the cell. - @return A cell dequeued from the reuse pool or newly created. - - @note This method uses a string representation of the cell class as the identifier. + @return A cell dequeued from the reuse pool or a newly created one. */ - (__kindof UICollectionViewCell *)dequeueReusableCellFromStoryboardWithIdentifier:(NSString *)identifier forSectionController:(IGListSectionController *)sectionController atIndex:(NSInteger)index; /** - Dequeues a supplementary view from the UICollectionView reuse pool. + Dequeues a supplementary view from the collection view reuse pool. @param elementKind The kind of supplementary veiw. @param sectionController The section controller requesting this information. @param viewClass The class of the supplementary view. @param index The index of the supplementary vew. - @return A supplementary view dequeued from the reuse pool or newly created. + @return A supplementary view dequeued from the reuse pool or a newly created one. @note This method uses a string representation of the view class as the identifier. */ @@ -140,6 +140,39 @@ NS_ASSUME_NONNULL_BEGIN class:(Class)viewClass atIndex:(NSInteger)index; +/** + Dequeues a supplementary view from the collection view reuse pool. + + @param elementKind The kind of supplementary veiw. + @param identifier The identifier of the supplementary view in storyboard. + @param sectionController The section controller requesting this information. + @param index The index of the supplementary vew. + + @return A supplementary view dequeued from the reuse pool or a newly created one. + */ +- (__kindof UICollectionReusableView *)dequeueReusableSupplementaryViewFromStoryboardOfKind:(NSString *)elementKind + withIdentifier:(NSString *)identifier + forSectionController:(IGListSectionController *)sectionController + atIndex:(NSInteger)index; +/** + Dequeues a supplementary view from the collection view reuse pool. + + @param elementKind The kind of supplementary veiw. + @param sectionController The section controller requesting this information. + @param nibName The name of the nib file. + @param bundle The bundle in which to search for the nib file. If `nil`, this method searches the main bundle. + @param index The index of the supplementary vew. + + @return A supplementary view dequeued from the reuse pool or a newly created one. + + @note This method uses a string representation of the view class as the identifier. + */ +- (__kindof UICollectionReusableView *)dequeueReusableSupplementaryViewOfKind:(NSString *)elementKind + forSectionController:(IGListSectionController *)sectionController + nibName:(NSString *)nibName + bundle:(nullable NSBundle *)bundle + atIndex:(NSInteger)index; + /** Reloads cells in the section controller. @@ -150,7 +183,7 @@ NS_ASSUME_NONNULL_BEGIN atIndexes:(NSIndexSet *)indexes; /** - Inserts cells in the feed. + Inserts cells in the list. @param sectionController The section controller who's cells need inserting. @param indexes The indexes of items that need inserting. @@ -159,7 +192,7 @@ NS_ASSUME_NONNULL_BEGIN atIndexes:(NSIndexSet *)indexes; /** - Deletes cells in the feed. + Deletes cells in the list. @param sectionController The section controller who's cells need deleted. @param indexes The indexes of items that need deleting. @@ -168,25 +201,26 @@ NS_ASSUME_NONNULL_BEGIN atIndexes:(NSIndexSet *)indexes; /** - Reload the entire section controller. + Reloads the entire section controller. - @param sectionController The list object who's cells need reloading. + @param sectionController The section controller who's cells need reloading. */ - (void)reloadSectionController:(IGListSectionController *)sectionController; /** - Batch many cell-level updates in a single transaction. + Batches and performs many cell-level updates in a single transaction. @param animated A flag indicating if the transition should be animated. @param updates A block containing all of the cell updates. @param completion An optional completion block to execute when the updates are finished. - @discussion Use this method to batch cell updates (inserts, deletes, reloads) into a single transaction. This lets you + @note Use this method to batch cell updates (inserts, deletes, reloads) into a single transaction. This lets you make many changes to your data store and perform all the transitions at once. - For example, inside your section controllers, you may want to delete /and/ insert into the data source that backs your - section controller: + For example, inside your section controllers, you may want to delete *and* insert into the data source that backs your + section controller. For example: + ``` [self.collectionContext performBatchItemUpdates:^{ // perform data source changes inside the update block [self.items addObject:newItem]; @@ -198,8 +232,9 @@ NS_ASSUME_NONNULL_BEGIN NSIndexSet *deletes = [NSIndexSet indexSetWithIndex:0]; [self.collectionContext deleteInSectionController:self deletes]; } completion:nil]; + ``` - Note that you **must** perform data modifications **inside** the update block. Updates will not be performed + @warning You **must** perform data modifications **inside** the update block. Updates will not be performed synchronously, so you should make sure that your data source changes only when necessary. */ - (void)performBatchAnimated:(BOOL)animated updates:(void (^)())updates completion:(nullable void (^)(BOOL finished))completion; diff --git a/Source/IGListCollectionView.h b/Source/IGListCollectionView.h index af612289f..dcd85d02a 100644 --- a/Source/IGListCollectionView.h +++ b/Source/IGListCollectionView.h @@ -12,28 +12,77 @@ #import /** - This class is never actually used by the IGListKit infrastructure. It exists only to give compiler errors when editing - methods are called on the collection view returned by -[IGListAdapter collectionView]. + This class is never actually used by the `IGListKit` infrastructure. + It exists only to give compiler errors when editing + methods are called on the collection view returned by `-[IGListAdapter collectionView]`. */ IGLK_SUBCLASSING_RESTRICTED @interface IGListCollectionView : UICollectionView -- (void)performBatchUpdates:(void (^)(void))updates completion:(void (^)(BOOL))completion IGLK_UNAVAILABLE("Call -[IGListAdapter performUpdatesWithCompletion:] instead"); +/** + :nodoc: + */ +- (void)performBatchUpdates:(void (^)(void))updates + completion:(void (^)(BOOL))completion IGLK_UNAVAILABLE("Call -[IGListAdapter performUpdatesWithCompletion:] instead"); +/** + :nodoc: + */ - (void)reloadData IGLK_UNAVAILABLE("Call -[IGListAdapter reloadDataWithCompletion:] instead"); + +/** + :nodoc: + */ - (void)reloadSections:(NSIndexSet *)sections IGLK_UNAVAILABLE("Call -[IGListAdapter reloadItems:] instead"); +/** + :nodoc: + */ - (void)insertSections:(NSIndexSet *)sections IGLK_UNAVAILABLE("Call -[IGListAdapter performUpdatesWithCompletion:] instead"); + +/** + :nodoc: + */ - (void)deleteSections:(NSIndexSet *)sections IGLK_UNAVAILABLE("Call -[IGListAdapter performUpdatesWithCompletion:] instead"); + +/** + :nodoc: + */ - (void)moveSection:(NSInteger)section toSection:(NSInteger)newSection IGLK_UNAVAILABLE("Call -[IGListAdapter performUpdatesWithCompletion:] instead"); +/** + :nodoc: + */ - (void)insertItemsAtIndexPaths:(NSArray *)indexPaths IGLK_UNAVAILABLE("Call -[ insertSectionController:forItems:completion:] instead"); + +/** + :nodoc: + */ - (void)reloadItemsAtIndexPaths:(NSArray *)indexPaths IGLK_UNAVAILABLE("Call -[ reloadSectionController:forItems:completion:] instead"); + +/** + :nodoc: + */ - (void)deleteItemsAtIndexPaths:(NSArray *)indexPaths IGLK_UNAVAILABLE("Call -[ deleteSectionController:forItems:completion:] instead"); + +/** + :nodoc: + */ - (void)moveItemAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath IGLK_UNAVAILABLE("Moving items currently unsupported"); +/** + :nodoc: + */ - (void)setDelegate:(id)delegate IGLK_UNAVAILABLE("IGListAdapter should be the delegate of the collection view"); + +/** + :nodoc: + */ - (void)setDataSource:(id)dataSource IGLK_UNAVAILABLE("IGListAdapter should be the data source of the collection view"); + +/** + :nodoc: + */ - (void)setBackgroundView:(UIView *)backgroundView IGLK_UNAVAILABLE("Return a view in -[IGListAdapterDataSource emptyViewForListAdapter:] instead"); @end diff --git a/Source/IGListDiff.h b/Source/IGListDiff.h index 586c842c4..a2a4a7562 100644 --- a/Source/IGListDiff.h +++ b/Source/IGListDiff.h @@ -16,7 +16,7 @@ NS_ASSUME_NONNULL_BEGIN /** - An option on how to do comparisons between similar objects. + An option for how to do comparisons between similar objects. */ typedef NS_ENUM(NSUInteger, IGListDiffOption) { /** @@ -24,34 +24,34 @@ typedef NS_ENUM(NSUInteger, IGListDiffOption) { */ IGListDiffPointerPersonality, /** - Compare objects using -[NSObject isEqual:]. + Compare objects using `-[NSObject isEqual:]`. */ IGListDiffEquality }; /** - Create a diff using indexes between two collections. + Creates a diff using indexes between two collections. @param oldArray The old objects to diff against. - @param newArray The new objects to diff with. + @param newArray The new objects. @param option An option on how to compare objects. - @return Result object with effected indexes. + @return A result object containing affected indexes. */ FOUNDATION_EXTERN IGListIndexSetResult *IGListDiff(NSArray > *_Nullable oldArray, NSArray> *_Nullable newArray, IGListDiffOption option); /** - Create a diff using index paths between two collections. + Creates a diff using index paths between two collections. - @param fromSection The old section used to seed returned index paths. - @param toSection The new section used to seed returned index paths. + @param fromSection The old section. + @param toSection The new section. @param oldArray The old objects to diff against. - @param newArray The new objects to diff with. + @param newArray The new objects. @param option An option on how to compare objects. - @return Result object with effected index paths. + @return A result object containing affected indexes. */ FOUNDATION_EXTERN IGListIndexPathResult *IGListDiffPaths(NSInteger fromSection, NSInteger toSection, diff --git a/Source/IGListDiff.mm b/Source/IGListDiff.mm index 91dd718e7..0fcbd76a2 100644 --- a/Source/IGListDiff.mm +++ b/Source/IGListDiff.mm @@ -137,7 +137,7 @@ static id IGListDiffing(BOOL returnIndexPaths, case IGListDiffEquality: // use -[IGListDiffable isEqual:] between both version of data to see if anything has changed // skip the equality check if both indexes point to the same object - if (n != o && ![n isEqual:o]) { + if (n != o && ![n isEqualToDiffableObject:o]) { entry->updated = YES; } break; diff --git a/Source/IGListDiffable.h b/Source/IGListDiffable.h index ae6fb517b..937a1eb7d 100644 --- a/Source/IGListDiffable.h +++ b/Source/IGListDiffable.h @@ -10,8 +10,7 @@ #import /** - The IGListDiffable protocol provides the base methods needed to compare the identity and equality of two objects using - one of the IGListDiff functions. + The `IGListDiffable` protocol provides methods needed to compare the identity and equality of two objects. */ @protocol IGListDiffable @@ -20,8 +19,8 @@ @return A key that can be used to uniquely identify the object. - @discussion Two objects may share the same identifier, but are not equal. A common pattern is to import IGListCommon.h - and use the NSObject category for automatic conformance. However this means that objects will be identified on their + @note Two objects may share the same identifier, but are not equal. A common pattern is to use the `NSObject` + category for automatic conformance. However this means that objects will be identified on their pointer value so finding updates becomes impossible. @warning This value should never be mutated. @@ -29,19 +28,12 @@ - (nonnull id)diffIdentifier; /** - Returns a Boolean value that indicates whether the receiver and a given object are equal. + Returns whether the receiver and a given object are equal. @param object The object to be compared to the receiver. - @return YES if the receiver and object are equal, otherwise NO. - - @warning If you implement a custom isEqual: you must also implement -hash. You can just use the -diffIdentifier value - for your hash function: - - - (NSUInteger)hash { - return [[self diffIdentifier] hash]; - } + @return `YES` if the receiver and object are equal, otherwise `NO`. */ -- (BOOL)isEqual:(nullable id)object; +- (BOOL)isEqualToDiffableObject:(nullable id)object; @end diff --git a/Source/IGListDisplayDelegate.h b/Source/IGListDisplayDelegate.h index bc2291762..00321da25 100644 --- a/Source/IGListDisplayDelegate.h +++ b/Source/IGListDisplayDelegate.h @@ -22,40 +22,40 @@ NS_ASSUME_NONNULL_BEGIN @protocol IGListDisplayDelegate /** - Tells the delegate that the specified list is about to be displayed. + Tells the delegate that the specified section controller is about to be displayed. - @param listAdapter The list adapter that the list will display in. - @param sectionController The list about to be displayed. + @param listAdapter The list adapter for the section controller. + @param sectionController The section controller about to be displayed. */ - (void)listAdapter:(IGListAdapter *)listAdapter willDisplaySectionController:(IGListSectionController *)sectionController; /** - Tells the delegate that the specified list is no longer being displayed. + Tells the delegate that the specified section controller is no longer being displayed. - @param listAdapter The list adapter that the list was displayed in. - @param sectionController The list that is no longer displayed. + @param listAdapter The list adapter for the section controller. + @param sectionController The section controller that is no longer displayed. */ - (void)listAdapter:(IGListAdapter *)listAdapter didEndDisplayingSectionController:(IGListSectionController *)sectionController; /** - Tells the delegate that a row in the specified list is about to be displayed. + Tells the delegate that a cell in the specified list is about to be displayed. - @param listAdapter The list adapter that row will display in. - @param sectionController The section controller that is displaying. + @param listAdapter The list adapter in which the cell will display. + @param sectionController The section controller that is displaying the cell. @param cell The cell about to be displayed. - @param index The index of the row. + @param index The index of the cell in the section. */ - (void)listAdapter:(IGListAdapter *)listAdapter willDisplaySectionController:(IGListSectionController *)sectionController cell:(UICollectionViewCell *)cell atIndex:(NSInteger)index; /** - Tells the delegate that a row in the specified list is no longer being displayed. + Tells the delegate that a cell in the specified list is no longer being displayed. - @param listAdapter The list adapter that the list was displayed in. + @param listAdapter The list adapter in which the cell was displayed. @param sectionController The section controller that is no longer displaying the cell. @param cell The cell that is no longer displayed. - @param index The index of the row. + @param index The index of the cell in the section. */ - (void)listAdapter:(IGListAdapter *)listAdapter didEndDisplayingSectionController:(IGListSectionController *)sectionController cell:(UICollectionViewCell *)cell diff --git a/Source/IGListExperiments.h b/Source/IGListExperiments.h index fd85f2ec5..a5a05f961 100644 --- a/Source/IGListExperiments.h +++ b/Source/IGListExperiments.h @@ -12,11 +12,10 @@ #import /** - Bitmask-able options used for prerelease feature testing. + Bitmask-able options used for pre-release feature testing. */ typedef NS_OPTIONS (NSUInteger, IGListExperiment) { - IGListExperimentLayoutBeforeUpdate = 1 << 0, - IGListExperimentUICVReloadedInSetter = 1 << 1, + IGListExperimentNone = 1 << 1, }; /** @@ -25,7 +24,7 @@ typedef NS_OPTIONS (NSUInteger, IGListExperiment) { @param mask The bitmask of experiments. @param option The option to compare with. - @return YES if the option is in the bitmask, otherwise NO. + @return `YES` if the option is in the bitmask, otherwise `NO`. */ static inline BOOL IGListExperimentEnabled(IGListExperiment mask, IGListExperiment option) { return (mask & option) != 0; @@ -34,7 +33,9 @@ static inline BOOL IGListExperimentEnabled(IGListExperiment mask, IGListExperime NS_ASSUME_NONNULL_BEGIN /** - Perform a diff with an experiment bitmask. See IGListDiff() in IGListDiff.h + Performs a diff with an experiment bitmask. + + @see `IGListDiff()`. */ FOUNDATION_EXTERN IGListIndexSetResult *IGListDiffExperiment(NSArray> *_Nullable oldArray, NSArray> *_Nullable newArray, @@ -42,7 +43,9 @@ FOUNDATION_EXTERN IGListIndexSetResult *IGListDiffExperiment(NSArray *inserts; /** - Index paths deleted from the old collection. + The index paths deleted from the old collection. */ @property (nonatomic, copy, readonly) NSArray *deletes; /** - Index paths in the new collection that need updated. + The index paths in the new collection that need updated. */ @property (nonatomic, copy, readonly) NSArray *updates; /** - Moves from an index path in the old collection to an index path in the new collection. + The moves from an index path in the old collection to an index path in the new collection. */ @property (nonatomic, copy, readonly) NSArray *moves; /** - Convenience to query if the result has any changes. + Returns whether the result has any changes or not. - @return YES if the result has changes, NO otherwise. + @return `YES` if the result has changes, `NO` otherwise. */ - (BOOL)hasChanges; /** - Fetch the index path of the object with identifier before the diff. + Returns the index path of the object with the specified identifier *before* the diff. - @param identifier The diff identifier of the object. See -[IGListDiffable diffIdentifier]. + @param identifier The diff identifier of the object. - @return The index path of the object before the diff, or nil. + @return The index path of the object before the diff, or `nil`. + + @see `-[IGListDiffable diffIdentifier]`. */ - (nullable NSIndexPath *)oldIndexPathForIdentifier:(id)identifier; /** - Fetch the index path of the object with identifier after the diff. + Returns the index path of the object with the specified identifier *after* the diff. - @param identifier The diff identifier of the object. See -[IGListDiffable diffIdentifier]. + @param identifier The diff identifier of the object. - @return The index path of the object after the diff, or nil. + @return The index path of the object after the diff, or `nil`. + + @see `-[IGListDiffable diffIdentifier]`. */ - (nullable NSIndexPath *)newIndexPathForIdentifier:(id)identifier; /** - Create a new result object with operations safe for use in UITableView and UICollectionView batch updates. + Creates a new result object with operations safe for use in `UITableView` and `UICollectionView` batch updates. */ - (IGListIndexPathResult *)resultForBatchUpdates; +/** + :nodoc: + */ - (instancetype)init NS_UNAVAILABLE; + +/** + :nodoc: + */ + (instancetype)new NS_UNAVAILABLE; @end diff --git a/Source/IGListIndexSetResult.h b/Source/IGListIndexSetResult.h index d6c3dc174..6348930d2 100644 --- a/Source/IGListIndexSetResult.h +++ b/Source/IGListIndexSetResult.h @@ -14,61 +14,72 @@ NS_ASSUME_NONNULL_BEGIN /** - Result object returned when diffing with indexes. + A result object returned when diffing with indexes. */ @interface IGListIndexSetResult : NSObject /** - Indexes inserted into the new collection. + The indexes inserted into the new collection. */ @property (nonatomic, strong, readonly) NSIndexSet *inserts; /** - Indexes deleted from the old collection. + The indexes deleted from the old collection. */ @property (nonatomic, strong, readonly) NSIndexSet *deletes; /** - Indexes in the new collection that need updated. + The indexes in the new collection that need updated. */ @property (nonatomic, strong, readonly) NSIndexSet *updates; /** - Moves from an index in the old collection to an index in the new collection. + The moves from an index in the old collection to an index in the new collection. */ @property (nonatomic, copy, readonly) NSArray *moves; /** - Convenience to query if the result has any changes. + Returns whether the result has any changes or not. - @return YES if the result has changes, NO otherwise. + @return `YES` if the result has changes, `NO` otherwise. */ - (BOOL)hasChanges; /** - Fetch the index of the object with identifier before the diff. + Returns the index of the object with the specified identifier *before* the diff. - @param identifier The diff identifier of the object. See -[IGListDiffable diffIdentifier]. + @param identifier The diff identifier of the object. - @return The index of the object before the diff, or NSNotFound. + @return The index of the object before the diff, or `NSNotFound`. + + @see `-[IGListDiffable diffIdentifier]`. */ - (NSUInteger)oldIndexForIdentifier:(id)identifier; /** - Fetch the index of the object with identifier after the diff. + Returns the index of the object with the specified identifier *after* the diff. + + @param identifier The diff identifier of the object. - @param identifier The diff identifier of the object. See -[IGListDiffable diffIdentifier]. + @return The index path of the object after the diff, or `NSNotFound`. - @return The index of the object after the diff, or NSNotFound. + @see `-[IGListDiffable diffIdentifier]`. */ - (NSUInteger)newIndexForIdentifier:(id)identifier; /** - Create a new result object with operations safe for use in UITableView and UICollectionView batch updates. + Creates a new result object with operations safe for use in `UITableView` and `UICollectionView` batch updates. */ - (IGListIndexSetResult *)resultForBatchUpdates; +/** + :nodoc: + */ - (instancetype)init NS_UNAVAILABLE; + +/** + :nodoc: + */ + (instancetype)new NS_UNAVAILABLE; @end diff --git a/Source/IGListMoveIndex.h b/Source/IGListMoveIndex.h index ab29fa747..8718f08f3 100644 --- a/Source/IGListMoveIndex.h +++ b/Source/IGListMoveIndex.h @@ -26,7 +26,14 @@ NS_ASSUME_NONNULL_BEGIN */ @property (nonatomic, assign, readonly) NSUInteger to; +/** + :nodoc: + */ - (instancetype)init NS_UNAVAILABLE; + +/** + :nodoc: + */ + (instancetype)new NS_UNAVAILABLE; @end diff --git a/Source/IGListMoveIndexPath.h b/Source/IGListMoveIndexPath.h index 45bbb1024..9cb91f880 100644 --- a/Source/IGListMoveIndexPath.h +++ b/Source/IGListMoveIndexPath.h @@ -26,7 +26,14 @@ NS_ASSUME_NONNULL_BEGIN */ @property (nonatomic, strong, readonly) NSIndexPath *to; +/** + :nodoc: + */ - (instancetype)init NS_UNAVAILABLE; + +/** + :nodoc: + */ + (instancetype)new NS_UNAVAILABLE; @end diff --git a/Source/IGListReloadDataUpdater.h b/Source/IGListReloadDataUpdater.h index bbfa4be40..342732a09 100644 --- a/Source/IGListReloadDataUpdater.h +++ b/Source/IGListReloadDataUpdater.h @@ -12,6 +12,12 @@ #import #import +/** + An `IGListReloadDataUpdater` is a concrete type that conforms to `IGListUpdatingDelegate`. + It is an out-of-box upater for `IGListAdapter` objects to use. + + @note This updater performs simple, synchronous updates using `-[UICollectionView reloadData]`. + */ IGLK_SUBCLASSING_RESTRICTED @interface IGListReloadDataUpdater : NSObject diff --git a/Source/IGListSectionController.h b/Source/IGListSectionController.h index 22a2a827d..68d99a92d 100644 --- a/Source/IGListSectionController.h +++ b/Source/IGListSectionController.h @@ -16,88 +16,91 @@ #import /** - The base class for section controllers used in the list infra. This class is meant to be subclassed. + The base class for section controllers used in a list. This class is intended to be subclassed. */ @interface IGListSectionController : NSObject /** The view controller housing the adapter that created this section controller. - @discussion Use this view controller to push, pop, present, or do other custom transitions. It is considered very bad - practice to cast this to a known view controller and call methods on it other than for navigations and transitions. + @note Use this view controller to push, pop, present, or do other custom transitions. + + @warning It is considered very bad practice to cast this to a known view controller + and call methods on it other than for navigations and transitions. */ @property (nonatomic, weak, nullable, readonly) UIViewController *viewController; /** - A context object for interacting with the collection i.e. accessing the collection size, dequeing cells, - reloading/inserting/deleting, etc. + A context object for interacting with the collection. + + Use this property for accessing the collection size, dequeing cells, reloading, inserting, deleting, etc. */ @property (nonatomic, weak, nullable, readonly) id collectionContext; /** - Returns YES if the section controller is the first section in the list. + Returns `YES` if the section controller is the first section in the list, `NO` otherwise. */ @property (nonatomic, assign, readonly) BOOL isFirstSection; /** - Returns YES if the section controller is the last section in the list. + Returns `YES` if the section controller is the last section in the list, `NO` otherwise. */ @property (nonatomic, assign, readonly) BOOL isLastSection; /** The margins used to lay out content in the section controller. - @see -[UICollectionViewFlowLayout sectionInset] + @see `-[UICollectionViewFlowLayout sectionInset]`. */ @property (nonatomic, assign) UIEdgeInsets inset; /** The minimum spacing to use between rows of items. - @see -[UICollectionViewFlowLayout minimumLineSpacing] + @see `-[UICollectionViewFlowLayout minimumLineSpacing]`. */ @property (nonatomic, assign) CGFloat minimumLineSpacing; /** The minimum spacing to use between items in the same row. - @see -[UICollectionViewFlowLayout minimumInteritemSpacing] + @see `-[UICollectionViewFlowLayout minimumInteritemSpacing]`. */ @property (nonatomic, assign) CGFloat minimumInteritemSpacing; /** - The supplementary view source for the section controller. Can be nil. + The supplementary view source for the section controller. Can be `nil`. - @return An object that conforms to IGListSupplementaryViewSource or nil. + @return An object that conforms to `IGListSupplementaryViewSource` or `nil`. - @discussion You may wish to return self if your section controller implements this protocol. + @note You may wish to return `self` if your section controller implements this protocol. */ @property (nonatomic, weak, nullable) id supplementaryViewSource; /** - An object that handles display events for the section controller. Can be nil. + An object that handles display events for the section controller. Can be `nil`. - @return An object that conforms to IGListDisplayDelegate or nil. + @return An object that conforms to `IGListDisplayDelegate` or `nil`. - @discussion You may wish to return self if your section controller implements this protocol. + @note You may wish to return `self` if your section controller implements this protocol. */ @property (nonatomic, weak, nullable) id displayDelegate; /** - An object that handles working range events for the section controller. Can be nil. + An object that handles working range events for the section controller. Can be `nil`. - @return An object that conforms to IGListWorkingRangeDelegate or nil. + @return An object that conforms to `IGListWorkingRangeDelegate` or `nil`. - @discussion You may wish to return self if your section controller implements this protocol. + @note You may wish to return `self` if your section controller implements this protocol. */ @property (nonatomic, weak, nullable) id workingRangeDelegate; /** - An object that handles display events for the section controller. Can be nil. + An object that handles display events for the section controller. Can be `nil`. - @return An object that conforms to IGListDisplayDelegate or nil. + @return An object that conforms to `IGListDisplayDelegate` or `nil`. - @discussion You may wish to return self if your section controller implements this protocol. + @note You may wish to return `self` if your section controller implements this protocol. */ @property (nonatomic, weak, nullable) id scrollDelegate; diff --git a/Source/IGListSectionType.h b/Source/IGListSectionType.h index 62a3dbc75..72193df0f 100644 --- a/Source/IGListSectionType.h +++ b/Source/IGListSectionType.h @@ -16,26 +16,26 @@ NS_ASSUME_NONNULL_BEGIN /** - Implement this protocol in order to be used within the IGListKit data infrastructure and be registered for use in an - IGListAdapter. An IGListSectionType conforming object represents a single instance of an object in a collection of + Implement this protocol in order to be used within the `IGListKit` data infrastructure and be registered for use in an + `IGListAdapter`. An `IGListSectionType` conforming object represents a single instance of an object in a collection of objects. - The infrastructure uses each IGListSectionType conforming object as a "view model" to populate and control cells as - part of a section in a UICollectionView feed. IGListSectionType objects should be architected without knowledge of - "global" state of the feed they are contained in. + The infrastructure uses each `IGListSectionType` conforming object as a "view model" to populate and control cells as + part of a section in a `UICollectionView`. `IGListSectionType` objects should be architected without knowledge of + "global" state of the list in which they are contained. Index paths are used as a convenience for communicating the section index to each section object without allowing each - section to mutate its own position within a feed. The row of an index path can be directly mapped to a cell within - an IGListSectionType conforming object. + section to mutate its own position within a list. The row of an index path can be directly mapped to a cell within + an `IGListSectionType` conforming object. */ @protocol IGListSectionType /** - The number of items in the IGListSectionType. + Returns the number of items in the section. @return A count of items in the list. - @discussion The count returned is used to drive the number of cells displayed for this list. You are free to change + @note The count returned is used to drive the number of cells displayed for this list. You are free to change this value between data loading passes. */ - (NSInteger)numberOfItems; @@ -47,44 +47,42 @@ NS_ASSUME_NONNULL_BEGIN @return The size for the item at index. - @discussion The returned size is not garaunteed to be used. The feed implementation may query list items for their - layout information at will, or use its own layout metrics. For example, consider a dynamic-text sized feed vs. a fixed - height-and-width grid feed. The former will ask each IGListSectionType for a size, and the latter will likely not. + @note The returned size is not garaunteed to be used. The implementation may query sections for their + layout information at will, or use its own layout metrics. For example, consider a dynamic-text sized list versus a fixed + height-and-width grid. The former will ask each section for a size, and the latter will likely not. */ - (CGSize)sizeForItemAtIndex:(NSInteger)index; /** - Asks the section controller for a fully configured cell at an index path. + Asks the section controller for a fully configured cell at the specified index. @param index The index of the requested row. - @return A configured UICollectionViewCell subclass. + @return A configured `UICollectionViewCell` subclass. - @discussion This is your opportunity to do any cell setup and configuration. The infrastructure requests a cell when it - will be used on screen. You should never allocate new cells in this method, instead on the provided adapter call - -dequeCellClass:forIndexPath: which either deques a cell from the UICollectionView or creates a new one for you. + @note This is your opportunity to do any cell setup and configuration. The infrastructure requests a cell when it + will be used on screen. You should never allocate new cells in this method, instead use the provided adapter to call + `-dequeCellClass:forIndexPath:` which either deques a cell from the collection view or creates a new one for you. */ - (__kindof UICollectionViewCell *)cellForItemAtIndex:(NSInteger)index; /** - Tells the IGListSectionType that the section controller was updated to a new item. + Tells the section that the controller was updated to a new object. @param object The object mapped to this section controller. - @discussion When this method is called, all available contexts and configurations have been set for the section + @note When this method is called, all available contexts and configurations have been set for the section controller. Also, depending on the updating strategy used, your item models may have changed objects in memory, so you can use this event to update the object stored on your section controller. - This method will only be called when the object instance has changed, either from nil or a previous object. + This method will only be called when the object instance has changed, including from `nil` or a previous object. */ - (void)didUpdateToObject:(id)object; /** - Tells the IGListSectionType that the cell at the specified index path was selected. + Tells the section that the cell at the specified index path was selected. @param index The index of the selected cell. - - @discussion Implementation of this method is required for compile-time safety, but you are free to do nothing. */ - (void)didSelectItemAtIndex:(NSInteger)index; diff --git a/Source/IGListSingleSectionController.h b/Source/IGListSingleSectionController.h index 1c939a2ac..a0ae50d75 100644 --- a/Source/IGListSingleSectionController.h +++ b/Source/IGListSingleSectionController.h @@ -15,13 +15,29 @@ NS_ASSUME_NONNULL_BEGIN + +/** + A block used to configure cells. + + @param item The model with which to configure the cell. + @param cell The cell to configure. + */ typedef void (^IGListSingleSectionCellConfigureBlock)(id item, __kindof UICollectionViewCell *cell); -typedef CGSize (^IGListSingleSectionCellSizeBlock)(id _Nullable collectionContext); + +/** + A block that returns the size for the cell given the collection context. + + @param item The model for the section. + @param collectionContext The collection context for the section. + + @return The for the cell. + */ +typedef CGSize (^IGListSingleSectionCellSizeBlock)(id item, id _Nullable collectionContext); @class IGListSingleSectionController; /** - A delegate that can receive selection events on an IGListSingleSectionController. + A delegate that can receive selection events on an `IGListSingleSectionController`. */ @protocol IGListSingleSectionControllerDelegate @@ -35,31 +51,30 @@ typedef CGSize (^IGListSingleSectionCellSizeBlock)(id _ @end /** - This section controller is meant to make building simple, single-cell feeds easier. By providing the type of cell, a block - to configure the cell, and a block to return the size of a cell, you can use an IGListAdapter-powered feed without - overcomplicating your architecture. + This section controller is meant to make building simple, single-cell lists easier. By providing the type of cell, a block + to configure the cell, and a block to return the size of a cell, you can use an IGListAdapter-powered list simpler architecture. */ IGLK_SUBCLASSING_RESTRICTED @interface IGListSingleSectionController : IGListSectionController /** - Create a new section controller for a given cell type that will always have only one cell when present in a feed. + Creates a new section controller for a given cell type that will always have only one cell when present in a list. - @param cellClass The UICollectionViewCell subclass for the single cell. + @param cellClass The `UICollectionViewCell` subclass for the single cell. @param configureBlock A block that configures the cell with the item given to the section controller. @param sizeBlock A block that returns the size for the cell given the collection context. @return A new section controller. @warning Be VERY CAREFUL not to create retain cycles by holding strong references to: the object that owns the adapter - (usually "self") or the IGListAdapter. Pass in locally scoped objects or use weak references! + (usually `self`) or the `IGListAdapter`. Pass in locally scoped objects or use `weak` references! */ - (instancetype)initWithCellClass:(Class)cellClass configureBlock:(IGListSingleSectionCellConfigureBlock)configureBlock sizeBlock:(IGListSingleSectionCellSizeBlock)sizeBlock; /** - Create a new section controller for a given nib name and bundle that will always have only one cell when present in a feed. + Creates a new section controller for a given nib name and bundle that will always have only one cell when present in a list. @param nibName The name of the nib file for the single cell. @param bundle The bundle in which to search for the nib file. If nil, this method looks for the file in the main bundle. @@ -67,9 +82,9 @@ IGLK_SUBCLASSING_RESTRICTED @param sizeBlock A block that returns the size for the cell given the collection context. @return A new section controller. - + @warning Be VERY CAREFUL not to create retain cycles by holding strong references to: the object that owns the adapter - (usually "self") or the IGListAdapter. Pass in locally scoped objects or use weak references! + (usually `self`) or the `IGListAdapter`. Pass in locally scoped objects or use `weak` references! */ - (instancetype)initWithNibName:(NSString *)nibName bundle:(nullable NSBundle *)bundle @@ -77,16 +92,16 @@ IGLK_SUBCLASSING_RESTRICTED sizeBlock:(IGListSingleSectionCellSizeBlock)sizeBlock; /** - Create a new section controller for a given storyboard cell identifier that will always have only one cell when present in a feed. + Creates a new section controller for a given storyboard cell identifier that will always have only one cell when present in a list. @param identifier The identifier of the cell prototype in storyboard. @param configureBlock A block that configures the cell with the item given to the section controller. @param sizeBlock A block that returns the size for the cell given the collection context. @return A new section controller. - + @warning Be VERY CAREFUL not to create retain cycles by holding strong references to: the object that owns the adapter - (usually "self") or the IGListAdapter. Pass in locally scoped objects or use weak references! + (usually `self`) or the `IGListAdapter`. Pass in locally scoped objects or use `weak` references! */ - (instancetype)initWithStoryboardCellIdentifier:(NSString *)identifier configureBlock:(IGListSingleSectionCellConfigureBlock)configureBlock @@ -97,7 +112,14 @@ IGLK_SUBCLASSING_RESTRICTED */ @property (nonatomic, weak, nullable) id selectionDelegate; +/** + :nodoc: + */ - (instancetype)init NS_UNAVAILABLE; + +/** + :nodoc: + */ + (instancetype)new NS_UNAVAILABLE; @end diff --git a/Source/IGListSingleSectionController.m b/Source/IGListSingleSectionController.m index 4217a343c..6bb35b5f2 100644 --- a/Source/IGListSingleSectionController.m +++ b/Source/IGListSingleSectionController.m @@ -78,7 +78,7 @@ - (NSInteger)numberOfItems { } - (CGSize)sizeForItemAtIndex:(NSInteger)index { - return self.sizeBlock(self.collectionContext); + return self.sizeBlock(self.item, self.collectionContext); } - (UICollectionViewCell *)cellForItemAtIndex:(NSInteger)index { diff --git a/Source/IGListStackedSectionController.h b/Source/IGListStackedSectionController.h index c98067759..07b21c26c 100644 --- a/Source/IGListStackedSectionController.h +++ b/Source/IGListStackedSectionController.h @@ -12,7 +12,8 @@ #import /** - This is a clustered section controller, composed of many child section controllers. It constructs and routes item-level + An instace of `IGListStackedSectionController` is a clustered section controller, + composed of many child section controllers. It constructs and routes item-level indexes to the appropriate child section controller with a local index. This lets you build section controllers made up of individual units that can be shared and reused with other section controllers. @@ -24,16 +25,24 @@ IGLK_SUBCLASSING_RESTRICTED @interface IGListStackedSectionController : IGListSectionController /** - Create a new stacked section controller. + Creates a new stacked section controller. @param sectionControllers An array of section controllers that make up the stack. - @discussion The order of the section controllers dictates the order in which they appear. The first section controller - that is the supplementary source decides which supplementary views get displayed. + @note The order of the section controllers dictates the order in which they appear. + + @warning The first section controller that is the supplementary source decides which supplementary views get displayed. */ - (instancetype)initWithSectionControllers:(NSArray *> *)sectionControllers NS_DESIGNATED_INITIALIZER; +/** + :nodoc: + */ - (instancetype)init NS_UNAVAILABLE; + +/** + :nodoc: + */ + (instancetype)new NS_UNAVAILABLE; @end diff --git a/Source/IGListStackedSectionController.m b/Source/IGListStackedSectionController.m index cf4e480bb..d307156a7 100644 --- a/Source/IGListStackedSectionController.m +++ b/Source/IGListStackedSectionController.m @@ -212,8 +212,8 @@ - (UICollectionViewCell *)dequeueReusableCellFromStoryboardWithIdentifier:(NSStr atIndex:(NSInteger)index { const NSUInteger offset = [self offsetForSectionController:sectionController]; return (UICollectionViewCell *_Nonnull)[self.collectionContext dequeueReusableCellFromStoryboardWithIdentifier:identifier - forSectionController:self - atIndex:(index + offset)]; + forSectionController:self + atIndex:(index + offset)]; } - (UICollectionReusableView *)dequeueReusableSupplementaryViewOfKind:(NSString *)elementKind @@ -227,6 +227,30 @@ - (UICollectionReusableView *)dequeueReusableSupplementaryViewOfKind:(NSString * atIndex:(index + offset)]; } +- (UICollectionReusableView *)dequeueReusableSupplementaryViewFromStoryboardOfKind:(NSString *)elementKind + withIdentifier:(NSString *)identifier + forSectionController:(IGListSectionController *)sectionController + atIndex:(NSInteger)index { + const NSUInteger offset = [self offsetForSectionController:sectionController]; + return (UICollectionViewCell *_Nonnull)[self.collectionContext dequeueReusableSupplementaryViewFromStoryboardOfKind:elementKind + withIdentifier:identifier + forSectionController:self + atIndex:(index + offset)]; +} + +- (UICollectionReusableView *)dequeueReusableSupplementaryViewOfKind:(NSString *)elementKind + forSectionController:(IGListSectionController *)sectionController + nibName:(NSString *)nibName + bundle:(NSBundle *)bundle + atIndex:(NSInteger)index { + const NSUInteger offset = [self offsetForSectionController:sectionController]; + return (UICollectionViewCell *_Nonnull)[self.collectionContext dequeueReusableSupplementaryViewOfKind:elementKind + forSectionController:self + nibName:nibName + bundle:bundle + atIndex:(index + offset)]; +} + - (void)reloadInSectionController:(IGListSectionController *)sectionController atIndexes:(NSIndexSet *)indexes { NSIndexSet *itemIndexes = [self itemIndexesForSectionController:sectionController indexes:indexes]; [self.collectionContext reloadInSectionController:self atIndexes:itemIndexes]; diff --git a/Source/IGListSupplementaryViewSource.h b/Source/IGListSupplementaryViewSource.h index 5df2de64d..c79718bb3 100644 --- a/Source/IGListSupplementaryViewSource.h +++ b/Source/IGListSupplementaryViewSource.h @@ -12,9 +12,9 @@ NS_ASSUME_NONNULL_BEGIN /** - Implement the methods of this protocol to provide information about a list's supplementary views. This data is used in - IGListAdapter which then configures and maintains a UICollectionView. The supplementary API reflects that in - UICollectionView, UICollectionViewLayout, and UICollectionViewDataSource. + Conform to this protocol to provide information about a list's supplementary views. This data is used in + `IGListAdapter` which then configures and maintains a `UICollectionView`. The supplementary API reflects that in + `UICollectionView`, `UICollectionViewLayout`, and `UICollectionViewDataSource`. */ @protocol IGListSupplementaryViewSource @@ -29,9 +29,9 @@ NS_ASSUME_NONNULL_BEGIN Asks the SupplementaryViewSource for a configured supplementary view for the specified kind and index. @param elementKind The kind of supplementary view being requested - @param index The index for the row being requested. + @param index The index for the supplementary veiw being requested. - @discussion This is your opportunity to do any supplementary view setup and configuration. + @note This is your opportunity to do any supplementary view setup and configuration. @warning You should never allocate new views in this method. Instead deque a view from the `IGListCollectionContext`. */ @@ -42,7 +42,7 @@ NS_ASSUME_NONNULL_BEGIN Asks the SupplementaryViewSource for the size of a supplementary view for the given kind and index path. @param elementKind The kind of supplementary view. - @param index The index of the requested row. + @param index The index of the requested view. @return The size for the supplementary view. */ diff --git a/Source/IGListUpdatingDelegate.h b/Source/IGListUpdatingDelegate.h index 67b78616e..cfb785117 100644 --- a/Source/IGListUpdatingDelegate.h +++ b/Source/IGListUpdatingDelegate.h @@ -13,9 +13,24 @@ NS_ASSUME_NONNULL_BEGIN +/** + A completion block to execute when updates are finished. + + @param finished Specifies whether or not the update finished. + */ typedef void (^IGListUpdatingCompletion)(BOOL finished); + +/** + A block to be called when the adapter applies changes to the collection view. + + @param toObjects The new objects in the collection. + */ typedef void (^IGListObjectTransitionBlock)(NSArray *toObjects); + +/// A block that contains all of the updates. typedef void (^IGListItemUpdateBlock)(); + +/// A block to be called when an adapter reloads the collection view. typedef void (^IGListReloadUpdateBlock)(); /** @@ -29,12 +44,12 @@ typedef void (^IGListReloadUpdateBlock)(); @return Pointer functions for looking up an object in a collection. - @discussion Since the updating delegate is responsible for transitioning between object sets, it becomes the "source of + @note Since the updating delegate is responsible for transitioning between object sets, it becomes the "source of truth" for how objects and their corresponding section controllers are mapped. This allows the updater to control if - objects are looked up by pointer, or more traditionally, with hash/isEqual. + objects are looked up by pointer, or more traditionally, with `-hash`/`-isEqual`. - For behavior similar to NSDictionary, simply return - +[NSPointerFunctions pointerFunctionsWithOptions:NSPointerFunctionsObjectPersonality]. + For behavior similar to `NSDictionary`, simply return + `+[NSPointerFunctions pointerFunctionsWithOptions:NSPointerFunctionsObjectPersonality]`. */ - (NSPointerFunctions *)objectLookupPointerFunctions; @@ -42,17 +57,17 @@ typedef void (^IGListReloadUpdateBlock)(); Tells the delegate to perform a section transition from an old array of objects to a new one. @param collectionView The collection view to perform the transition on. - @param fromObjects The previous objects in the collection view. Objects must conform to IGListDiffable. - @param toObjects The new objects in collection view. Objects must conform to IGListDiffable. + @param fromObjects The previous objects in the collection view. Objects must conform to `IGListDiffable`. + @param toObjects The new objects in collection view. Objects must conform to `IGListDiffable`. @param animated A flag indicating if the transition should be animated. @param objectTransitionBlock A block that must be called when the adapter applies changes to the collection view. @param completion A completion block to execute when the update is finished. - @discussion Implementations determine how to transition between objects. You can perform a diff on the objects, reload - each section, or simply call -reloadData on the collection view. In the end, the collection view must be setup with a - section for each object in the toObjects array. + @note Implementations determine how to transition between objects. You can perform a diff on the objects, reload + each section, or simply call `-reloadData` on the collection view. In the end, the collection view must be setup with a + section for each object in the `toObjects` array. - The `objectUpdateBlock` block should be called prior to making any UICollectionView updates, passing in the `toObjects` + The `objectTransitionBlock` block should be called prior to making any `UICollectionView` updates, passing in the `toObjects` that the updater is applying. */ - (void)performUpdateWithCollectionView:(UICollectionView *)collectionView @@ -65,7 +80,7 @@ typedef void (^IGListReloadUpdateBlock)(); /** Tells the delegate to perform item inserts at the given index paths. - @param collectionView The collection view to perform the transition on. + @param collectionView The collection view on which to perform the transition. @param indexPaths The index paths to insert items into. */ - (void)insertItemsIntoCollectionView:(UICollectionView *)collectionView indexPaths:(NSArray *)indexPaths; @@ -73,7 +88,7 @@ typedef void (^IGListReloadUpdateBlock)(); /** Tells the delegate to perform item deletes at the given index paths. - @param collectionView The collection view to perform the transition on. + @param collectionView The collection view on which to perform the transition. @param indexPaths The index paths to delete items from. */ - (void)deleteItemsFromCollectionView:(UICollectionView *)collectionView indexPaths:(NSArray *)indexPaths; @@ -81,7 +96,7 @@ typedef void (^IGListReloadUpdateBlock)(); /** Tells the delegate to perform item reloads at the given index paths. - @param collectionView The collection view to perform the transition on. + @param collectionView The collection view on which to perform the transition. @param indexPaths The index paths of items to reload. */ - (void)reloadItemsInCollectionView:(UICollectionView *)collectionView indexPaths:(NSArray *)indexPaths; diff --git a/Source/IGListWorkingRangeDelegate.h b/Source/IGListWorkingRangeDelegate.h index 4621fceb4..df050bb64 100644 --- a/Source/IGListWorkingRangeDelegate.h +++ b/Source/IGListWorkingRangeDelegate.h @@ -27,7 +27,7 @@ NS_ASSUME_NONNULL_BEGIN /** Notifies the delegate that an section controller will enter the working range. - @param listAdapter The adapter controlling the feed. + @param listAdapter The adapter controlling the list. @param sectionController The section controller entering the range. */ - (void)listAdapter:(IGListAdapter *)listAdapter sectionControllerWillEnterWorkingRange:(IGListSectionController *)sectionController; @@ -35,7 +35,7 @@ NS_ASSUME_NONNULL_BEGIN /** Notifies the delegate that an section controller exited the working range. - @param listAdapter The adapter controlling the feed. + @param listAdapter The adapter controlling the list. @param sectionController The section controller that exited the range. */ - (void)listAdapter:(IGListAdapter *)listAdapter sectionControllerDidExitWorkingRange:(IGListSectionController *)sectionController; diff --git a/Source/Internal/IGListAdapterInternal.h b/Source/Internal/IGListAdapterInternal.h index d14dca8f2..521292582 100644 --- a/Source/Internal/IGListAdapterInternal.h +++ b/Source/Internal/IGListAdapterInternal.h @@ -32,7 +32,8 @@ IGListCollectionContext __weak UICollectionView *_collectionView; } -@property (nonatomic, strong, readonly) id updatingDelegate; +@property (nonatomic, strong) id updatingDelegate; + @property (nonatomic, strong, readonly) IGListSectionMap *sectionMap; @property (nonatomic, strong, readonly) IGListDisplayHandler *displayHandler; @property (nonatomic, strong, readonly) IGListWorkingRangeHandler *workingRangeHandler; @@ -56,10 +57,12 @@ IGListCollectionContext @property (nonatomic, strong) NSMutableSet *registeredCellClasses; @property (nonatomic, strong) NSMutableSet *registeredNibNames; @property (nonatomic, strong) NSMutableSet *registeredSupplementaryViewIdentifiers; +@property (nonatomic, strong) NSMutableSet *registeredSupplementaryViewNibNames; - (NSArray *)indexPathsFromSectionController:(IGListSectionController *)sectionController indexes:(NSIndexSet *)indexes adjustForUpdateBlock:(BOOL)adjustForUpdateBlock; +- (NSIndexPath *)indexPathForSectionController:(IGListSectionController *)controller index:(NSInteger)index; @end diff --git a/Source/Internal/IGListSectionMap.h b/Source/Internal/IGListSectionMap.h index 92efb5a93..9b1206ab2 100644 --- a/Source/Internal/IGListSectionMap.h +++ b/Source/Internal/IGListSectionMap.h @@ -102,7 +102,10 @@ IGLK_SUBCLASSING_RESTRICTED */ - (void)enumerateUsingBlock:(void (^)(id object, IGListSectionController *sectionController, NSUInteger section, BOOL *stop))block; -- (id)init NS_UNAVAILABLE; +/** + :nodoc: + */ +- (instancetype)init NS_UNAVAILABLE; @end diff --git a/Source/Internal/IGListSectionMap.m b/Source/Internal/IGListSectionMap.m index 323cde0cf..bce0927a8 100644 --- a/Source/Internal/IGListSectionMap.m +++ b/Source/Internal/IGListSectionMap.m @@ -75,7 +75,12 @@ - (void)updateWithObjects:(NSArray *)objects sectionControllers:(NSArray *)secti } - (id)objectForSection:(NSUInteger)section { - return self.objects[section]; + NSArray *objects = self.objects; + if (section < objects.count) { + return objects[section]; + } else { + return nil; + } } - (NSUInteger)sectionForObject:(id)object { diff --git a/Source/Internal/NSIndexSet+PrettyDescription.m b/Source/Internal/NSIndexSet+PrettyDescription.m deleted file mode 100644 index cdf9e6e85..000000000 --- a/Source/Internal/NSIndexSet+PrettyDescription.m +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Copyright (c) 2016-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -#import "NSIndexSet+PrettyDescription.h" - -@implementation NSIndexSet (PrettyDescription) - -- (NSString *)prettyDescription { - NSMutableArray *indexes = [[NSMutableArray alloc] init]; - [self enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL * _Nonnull stop) { - [indexes addObject:@(idx)]; - }]; - return [indexes componentsJoinedByString:@", "]; -} - -@end diff --git a/Source/NSObject+IGListDiffable.h b/Source/NSObject+IGListDiffable.h index f5c7a654d..f7146c1fd 100644 --- a/Source/NSObject+IGListDiffable.h +++ b/Source/NSObject+IGListDiffable.h @@ -12,13 +12,13 @@ #import /** - This category adds diffing comparisons similar to adding the object into an NSSet, where the object's isEqual: method - drives the uniqueness of the object. + This category adds diffing comparisons similar to adding the object into an `NSSet`, + where the object's `-isEqual:` method drives the uniqueness of the object. - For instance, an NSString's isEqual: will compare the value of the strings. So if you were to diff @"cat" and @"cat" - each object would have the same diff identifier. + For instance, an `NSString`'s `-isEqual:` will compare the value of the strings. + So if you were to diff `@"cat"` and `@"cat"` each object would have the same diff identifier. - However objects that don't implement a custom isEqual: (e.g. the NSObject base class), the diff will default to simple + However objects that don't implement a custom `-isEqual:` (e.g. the `NSObject` base class), the diff will default to simple pointer comparisons to establish uniqueness. */ @interface NSObject (IGListDiffable) diff --git a/Source/NSObject+IGListDiffable.m b/Source/NSObject+IGListDiffable.m index 6bb18bdef..f42c1e103 100644 --- a/Source/NSObject+IGListDiffable.m +++ b/Source/NSObject+IGListDiffable.m @@ -15,4 +15,12 @@ @implementation NSObject (IGListDiffable) return self; } +- (BOOL)isEqualToDiffableObject:(id)object { + if (self == object) { + return YES; + } else { + return [self isEqual:object]; + } +} + @end diff --git a/Tests/Assets/IGTestNibSupplementaryView.xib b/Tests/Assets/IGTestNibSupplementaryView.xib new file mode 100644 index 000000000..501e79ab1 --- /dev/null +++ b/Tests/Assets/IGTestNibSupplementaryView.xib @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tests/Assets/IGTestStoryboard.storyboard b/Tests/Assets/IGTestStoryboard.storyboard index 4a6be3b16..e609cf30e 100644 --- a/Tests/Assets/IGTestStoryboard.storyboard +++ b/Tests/Assets/IGTestStoryboard.storyboard @@ -1,5 +1,5 @@ - + @@ -7,10 +7,10 @@ - + - + @@ -22,17 +22,17 @@ - - + + - + - + + + + + + + + + + + + + + + + + @@ -64,7 +84,7 @@ - + diff --git a/Tests/IGListAdapterStoryboardTests.m b/Tests/IGListAdapterStoryboardTests.m new file mode 100644 index 000000000..4b15e4629 --- /dev/null +++ b/Tests/IGListAdapterStoryboardTests.m @@ -0,0 +1,85 @@ +/** + * Copyright (c) 2016-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +#import + +#import "IGListAdapterInternal.h" +#import "IGListTestAdapterStoryboardDataSource.h" +#import "IGListStackedSectionControllerInternal.h" +#import "IGTestStoryboardViewController.h" +#import "IGTestStoryboardSupplementarySource.h" + +#define genTestObject(k, v) [[IGTestObject alloc] initWithKey:k value:v] + +static const CGRect kStackTestFrame = (CGRect){{0.0, 0.0}, {100.0, 100.0}}; + +@interface IGListAdapterStoryboardTests : XCTestCase + +@property (nonatomic, strong) UIWindow *window; +@property (nonatomic, strong) IGListCollectionView *collectionView; +@property (nonatomic, strong) IGListAdapter *adapter; +@property (nonatomic, strong) IGListTestAdapterStoryboardDataSource *dataSource; +@property (nonatomic, strong) IGListAdapterUpdater *updater; +@property (nonatomic, strong) IGTestStoryboardViewController *viewController; + +@end + +@implementation IGListAdapterStoryboardTests + +- (void)setUp { + [super setUp]; + + self.window = [[UIWindow alloc] initWithFrame:kStackTestFrame]; + UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"IGTestStoryboard" bundle:[NSBundle bundleForClass:self.class]]; + self.viewController = [storyboard instantiateViewControllerWithIdentifier:@"testVC"]; + [self.window addSubview:self.viewController.view]; + [self.viewController performSelectorOnMainThread:@selector(loadView) withObject:nil waitUntilDone:YES]; + self.collectionView = self.viewController.collectionView; + + self.dataSource = [[IGListTestAdapterStoryboardDataSource alloc] init]; + self.updater = [[IGListAdapterUpdater alloc] init]; + self.adapter = [[IGListAdapter alloc] initWithUpdater:self.updater viewController:self.viewController workingRangeSize:0]; +} + +- (void)tearDown { + [super tearDown]; + + self.adapter = nil; + self.collectionView = nil; + self.dataSource = nil; +} + +- (void)setupWithObjects:(NSArray *)objects { + self.dataSource.objects = objects; + self.adapter.collectionView = self.viewController.collectionView; + self.adapter.dataSource = self.dataSource; + [self.adapter reloadDataWithCompletion:nil]; + + IGTestStoryboardSupplementarySource *supplementarySource = [IGTestStoryboardSupplementarySource new]; + supplementarySource.collectionContext = self.adapter; + supplementarySource.supportedElementKinds = @[UICollectionElementKindSectionHeader]; + + IGListSectionController *controller = [self.adapter sectionControllerForObject:@1]; + controller.supplementaryViewSource = supplementarySource; + supplementarySource.sectionController = controller; + + [self.adapter performUpdatesAnimated:NO completion:nil]; + [self.collectionView layoutIfNeeded]; +} + +- (void)test_whenSupplementarySourceSupportsHeader { + [self setupWithObjects:@[genTestObject(@1, @"Foo")]]; + + XCTAssertNotNil([self.collectionView supplementaryViewForElementKind:UICollectionElementKindSectionHeader atIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]]); +} + + +@end diff --git a/Tests/IGListAdapterTests.m b/Tests/IGListAdapterTests.m index af94e9493..7ae1b17da 100644 --- a/Tests/IGListAdapterTests.m +++ b/Tests/IGListAdapterTests.m @@ -13,12 +13,18 @@ #import #import -#import #import "IGListAdapterInternal.h" #import "IGListTestAdapterDataSource.h" #import "IGListTestSection.h" #import "IGTestSupplementarySource.h" +#import "IGTestNibSupplementaryView.h" + +#define IGAssertEqualPoint(point, x, y, ...) \ +do { \ +CGPoint p = CGPointMake(x, y); \ +XCTAssertEqual(CGPointEqualToPoint(point, p), YES); \ +} while(0) @interface IGListAdapterTests : XCTestCase @@ -26,6 +32,7 @@ @interface IGListAdapterTests : XCTestCase @property (nonatomic, strong) IGListCollectionView *collectionView; @property (nonatomic, strong) IGListAdapter *adapter; @property (nonatomic, strong) IGListTestAdapterDataSource *dataSource; +@property (nonatomic, strong) UICollectionViewFlowLayout *layout; @property (nonatomic, strong) UIWindow *window; @end @@ -38,8 +45,8 @@ - (void)setUp { // minimum line spacing, item size, and minimum interim spacing are all set in IGListTestSection self.window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, 100, 100)]; - UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init]; - self.collectionView = [[IGListCollectionView alloc] initWithFrame:self.window.bounds collectionViewLayout:layout]; + self.layout = [[UICollectionViewFlowLayout alloc] init]; + self.collectionView = [[IGListCollectionView alloc] initWithFrame:self.window.bounds collectionViewLayout:self.layout]; [self.window addSubview:self.collectionView]; @@ -60,6 +67,7 @@ - (void)tearDown { self.collectionView = nil; self.adapter = nil; self.dataSource = nil; + self.layout = nil; } - (void)test_whenAdapterNotUpdated_withDataSourceUpdated_thatAdapterHasNoSectionControllers { @@ -380,6 +388,30 @@ - (void)test_whenSupplementarySourceSupportsFooter_thatHeaderViewsAreNil { XCTAssertNil([self.collectionView supplementaryViewForElementKind:UICollectionElementKindSectionFooter atIndexPath:[NSIndexPath indexPathForItem:0 inSection:1]]); } +- (void)test_whenSupplementarySourceSupportsFooter_withNibs_thatHeaderViewsAreNil { + self.dataSource.objects = @[@1, @2]; + [self.adapter reloadDataWithCompletion:nil]; + + IGTestSupplementarySource *supplementarySource = [IGTestSupplementarySource new]; + supplementarySource.dequeueFromNib = YES; + supplementarySource.collectionContext = self.adapter; + supplementarySource.supportedElementKinds = @[UICollectionElementKindSectionFooter]; + + IGListSectionController *controller = [self.adapter sectionControllerForObject:@1]; + controller.supplementaryViewSource = supplementarySource; + supplementarySource.sectionController = controller; + + [self.adapter performUpdatesAnimated:NO completion:nil]; + + id view = [self.collectionView supplementaryViewForElementKind:UICollectionElementKindSectionFooter atIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]]; + XCTAssertTrue([view isKindOfClass:IGTestNibSupplementaryView.class]); + XCTAssertEqualObjects([[(IGTestNibSupplementaryView *)view label] text], @"Foo bar baz"); + + XCTAssertNil([self.collectionView supplementaryViewForElementKind:UICollectionElementKindSectionHeader atIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]]); + XCTAssertNil([self.collectionView supplementaryViewForElementKind:UICollectionElementKindSectionHeader atIndexPath:[NSIndexPath indexPathForItem:0 inSection:1]]); + XCTAssertNil([self.collectionView supplementaryViewForElementKind:UICollectionElementKindSectionFooter atIndexPath:[NSIndexPath indexPathForItem:0 inSection:1]]); +} + - (void)test_whenAdapterReleased_withSectionControllerStrongRefToCell_thatSectionControllersRelease { __weak id weakCollectionView = nil, weakAdapter = nil, weakSectionController = nil; @@ -483,4 +515,217 @@ - (void)test_whenAdapterUpdatedTwice_withThreeSections_thatSectionsUpdatedFirstL XCTAssertFalse([[self.adapter sectionControllerForObject:@2] isLastSection]); } +- (void)test_whenAdapterUpdated_withObjectsOverflow_thatVisibleObjectsIsSubsetOfAllObjects { + // each section controller returns n items sized 100x10 + self.dataSource.objects = @[@1, @2, @3, @4, @5, @6]; + [self.adapter reloadDataWithCompletion:nil]; + self.collectionView.contentOffset = CGPointMake(0, 30); + [self.collectionView layoutIfNeeded]; + + NSArray *visibleObjects = [[self.adapter visibleObjects] sortedArrayUsingSelector:@selector(compare:)]; + NSArray *expectedObjects = @[@3, @4, @5]; + XCTAssertEqualObjects(visibleObjects, expectedObjects); +} + +- (void)test_whenScrollVerticallyToItem { + // # of items for each object == [item integerValue], so @2 has 2 items (cells) + self.dataSource.objects = @[@1, @2, @3, @4, @5, @6]; + [self.adapter reloadDataWithCompletion:nil]; + XCTAssertEqual([self.collectionView numberOfSections], 6); + [self.adapter scrollToObject:@1 supplementaryKinds:nil scrollDirection:UICollectionViewScrollDirectionVertical animated:NO]; + IGAssertEqualPoint([self.collectionView contentOffset], 0, 0); + [self.adapter scrollToObject:@2 supplementaryKinds:nil scrollDirection:UICollectionViewScrollDirectionVertical animated:NO]; + IGAssertEqualPoint([self.collectionView contentOffset], 0, 10); + [self.adapter scrollToObject:@3 supplementaryKinds:nil scrollDirection:UICollectionViewScrollDirectionVertical animated:NO]; + IGAssertEqualPoint([self.collectionView contentOffset], 0, 30); + [self.adapter scrollToObject:@6 supplementaryKinds:nil scrollDirection:UICollectionViewScrollDirectionVertical animated:NO]; + IGAssertEqualPoint([self.collectionView contentOffset], 0, 150); +} + +- (void)test_whenScrollHorizontallyToItem { + // # of items for each object == [item integerValue], so @2 has 2 items (cells) + self.dataSource.objects = @[@1, @2, @3, @4, @5, @6]; + self.layout.scrollDirection = UICollectionViewScrollDirectionHorizontal; + [self.adapter reloadDataWithCompletion:nil]; + XCTAssertEqual([self.collectionView numberOfSections], 6); + [self.adapter scrollToObject:@1 supplementaryKinds:nil scrollDirection:UICollectionViewScrollDirectionHorizontal animated:NO]; + IGAssertEqualPoint([self.collectionView contentOffset], 0, 0); + [self.adapter scrollToObject:@2 supplementaryKinds:nil scrollDirection:UICollectionViewScrollDirectionHorizontal animated:NO]; + IGAssertEqualPoint([self.collectionView contentOffset], 100, 0); + [self.adapter scrollToObject:@3 supplementaryKinds:nil scrollDirection:UICollectionViewScrollDirectionHorizontal animated:NO]; + IGAssertEqualPoint([self.collectionView contentOffset], 200, 0); + [self.adapter scrollToObject:@6 supplementaryKinds:nil scrollDirection:UICollectionViewScrollDirectionHorizontal animated:NO]; + IGAssertEqualPoint([self.collectionView contentOffset], 500, 0); + self.layout.scrollDirection = UICollectionViewScrollDirectionVertical; +} + +- (void)test_whenScrollToItem_thatSupplementarySourceSupportsSingleHeader { + self.dataSource.objects = @[@1, @2]; + [self.adapter reloadDataWithCompletion:nil]; + + IGTestSupplementarySource *supplementarySource = [IGTestSupplementarySource new]; + supplementarySource.collectionContext = self.adapter; + supplementarySource.supportedElementKinds = @[UICollectionElementKindSectionHeader]; + + IGListSectionController *controller = [self.adapter sectionControllerForObject:@1]; + controller.supplementaryViewSource = supplementarySource; + supplementarySource.sectionController = controller; + + [self.adapter performUpdatesAnimated:NO completion:nil]; + + XCTAssertNotNil([self.collectionView supplementaryViewForElementKind:UICollectionElementKindSectionHeader atIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]]); + [self.adapter scrollToObject:@1 supplementaryKinds:@[UICollectionElementKindSectionHeader] scrollDirection:UICollectionViewScrollDirectionVertical animated:NO]; + IGAssertEqualPoint([self.collectionView contentOffset], 0, 0); + [self.adapter scrollToObject:@2 supplementaryKinds:@[UICollectionElementKindSectionHeader] scrollDirection:UICollectionViewScrollDirectionVertical animated:NO]; + IGAssertEqualPoint([self.collectionView contentOffset], 0, 20); +} + +- (void)test_whenScrollToItem_thatSupplementarySourceSupportsHeaderAndFooter { + self.dataSource.objects = @[@1, @2]; + [self.adapter reloadDataWithCompletion:nil]; + + IGTestSupplementarySource *supplementarySource = [IGTestSupplementarySource new]; + supplementarySource.collectionContext = self.adapter; + supplementarySource.supportedElementKinds = @[UICollectionElementKindSectionHeader, UICollectionElementKindSectionFooter]; + + IGListSectionController *controller = [self.adapter sectionControllerForObject:@1]; + controller.supplementaryViewSource = supplementarySource; + supplementarySource.sectionController = controller; + + [self.adapter performUpdatesAnimated:NO completion:nil]; + + XCTAssertNotNil([self.collectionView supplementaryViewForElementKind:UICollectionElementKindSectionHeader atIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]]); + XCTAssertNotNil([self.collectionView supplementaryViewForElementKind:UICollectionElementKindSectionFooter atIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]]); + [self.adapter scrollToObject:@1 supplementaryKinds:@[UICollectionElementKindSectionHeader, UICollectionElementKindSectionFooter] scrollDirection:UICollectionViewScrollDirectionVertical animated:NO]; + IGAssertEqualPoint([self.collectionView contentOffset], 0, 0); + [self.adapter scrollToObject:@2 supplementaryKinds:@[UICollectionElementKindSectionHeader, UICollectionElementKindSectionFooter] scrollDirection:UICollectionViewScrollDirectionVertical animated:NO]; + IGAssertEqualPoint([self.collectionView contentOffset], 0, 30); +} + +- (void)test_whenScrollVerticallyToItem_thatFeedIsEmpty { + self.dataSource.objects = @[]; + [self.adapter reloadDataWithCompletion:nil]; + XCTAssertEqual([self.collectionView numberOfSections], 0); + [self.adapter scrollToObject:@1 supplementaryKinds:nil scrollDirection:UICollectionViewScrollDirectionVertical animated:NO]; + IGAssertEqualPoint([self.collectionView contentOffset], 0, 0); +} + +- (void)test_whenScrollVerticallyToItem_thatItemNotInFeed { + // # of items for each object == [item integerValue], so @2 has 2 items (cells) + self.dataSource.objects = @[@1, @2, @3, @4]; + [self.adapter reloadDataWithCompletion:nil]; + XCTAssertEqual([self.collectionView numberOfSections], 4); + [self.adapter scrollToObject:@1 supplementaryKinds:nil scrollDirection:UICollectionViewScrollDirectionVertical animated:NO]; + IGAssertEqualPoint([self.collectionView contentOffset], 0, 0); + [self.adapter scrollToObject:@5 supplementaryKinds:nil scrollDirection:UICollectionViewScrollDirectionVertical animated:NO]; + IGAssertEqualPoint([self.collectionView contentOffset], 0, 0); + [self.adapter scrollToObject:@2 supplementaryKinds:nil scrollDirection:UICollectionViewScrollDirectionVertical animated:NO]; + IGAssertEqualPoint([self.collectionView contentOffset], 0, 10); + [self.adapter scrollToObject:@5 supplementaryKinds:nil scrollDirection:UICollectionViewScrollDirectionVertical animated:NO]; + IGAssertEqualPoint([self.collectionView contentOffset], 0, 10); +} + +- (void)test_whenQueryingIndexPath_withOOBSectionController_thatNilReturned { + self.dataSource.objects = @[@0, @1, @2]; + [self.adapter reloadDataWithCompletion:nil]; + + id randomSectionController = [IGListSectionController new]; + XCTAssertNil([self.adapter indexPathForSectionController:randomSectionController index:0]); +} + +- (void)test_whenQueryingSectionForObject_thatSectionReturned { + self.dataSource.objects = @[@0, @1, @2]; + [self.adapter reloadDataWithCompletion:nil]; + XCTAssertEqual([self.adapter sectionForObject:@0], 0); + XCTAssertEqual([self.adapter sectionForObject:@1], 1); + XCTAssertEqual([self.adapter sectionForObject:@2], 2); + XCTAssertEqual([self.adapter sectionForObject:@3], NSNotFound); +} + +- (void)test_whenReloadingData_withNoDataSource_thatCompletionCalledWithNO { + self.dataSource.objects = @[@1]; + IGListAdapter *adapter = [[IGListAdapter alloc] initWithUpdater:[IGListReloadDataUpdater new] + viewController:nil + workingRangeSize:0]; + adapter.collectionView = self.collectionView; + + __block BOOL executed = NO; + [adapter reloadDataWithCompletion:^(BOOL finished) { + executed = YES; + XCTAssertFalse(finished); + }]; + XCTAssertTrue(executed); +} + +- (void)test_whenReloadingData_withNoCollectionView_thatCompletionCalledWithNO { + self.dataSource.objects = @[@1]; + IGListAdapter *adapter = [[IGListAdapter alloc] initWithUpdater:[IGListReloadDataUpdater new] + viewController:nil + workingRangeSize:0]; + adapter.dataSource = self.dataSource; + + __block BOOL executed = NO; + [adapter reloadDataWithCompletion:^(BOOL finished) { + executed = YES; + XCTAssertFalse(finished); + }]; + XCTAssertTrue(executed); +} + +- (void)test_whenSectionControllerReloading_withEmptyIndexes_thatNoUpdatesHappen { + self.dataSource.objects = @[@0, @1, @2]; + [self.adapter reloadDataWithCompletion:nil]; + + id mockDelegate = [OCMockObject mockForProtocol:@protocol(IGListUpdatingDelegate)]; + [[mockDelegate reject] reloadItemsInCollectionView:[OCMArg any] indexPaths:[OCMArg any]]; + self.adapter.updatingDelegate = mockDelegate; + + id sectionController = [self.adapter sectionControllerForObject:@1]; + [self.adapter reloadInSectionController:sectionController atIndexes:[NSIndexSet new]]; + + [mockDelegate verify]; +} + +- (void)test_whenSectionControllerDeleting_withEmptyIndexes_thatNoUpdatesHappen { + self.dataSource.objects = @[@0, @1, @2]; + [self.adapter reloadDataWithCompletion:nil]; + + id mockDelegate = [OCMockObject mockForProtocol:@protocol(IGListUpdatingDelegate)]; + [[mockDelegate reject] deleteItemsFromCollectionView:[OCMArg any] indexPaths:[OCMArg any]]; + self.adapter.updatingDelegate = mockDelegate; + + id sectionController = [self.adapter sectionControllerForObject:@1]; + [self.adapter deleteInSectionController:sectionController atIndexes:[NSIndexSet new]]; + + [mockDelegate verify]; +} + +- (void)test_whenSectionControllerInserting_withEmptyIndexes_thatNoUpdatesHappen { + self.dataSource.objects = @[@0, @1, @2]; + [self.adapter reloadDataWithCompletion:nil]; + + id mockDelegate = [OCMockObject mockForProtocol:@protocol(IGListUpdatingDelegate)]; + [[mockDelegate reject] insertItemsIntoCollectionView:[OCMArg any] indexPaths:[OCMArg any]]; + self.adapter.updatingDelegate = mockDelegate; + + id sectionController = [self.adapter sectionControllerForObject:@1]; + [self.adapter insertInSectionController:sectionController atIndexes:[NSIndexSet new]]; + + [mockDelegate verify]; +} + +- (void)test_whenReloading_withSectionControllerNotFound_thatNoUpdatesHappen { + self.dataSource.objects = @[@0, @1, @2]; + [self.adapter reloadDataWithCompletion:nil]; + + id mockDelegate = [OCMockObject mockForProtocol:@protocol(IGListUpdatingDelegate)]; + [[mockDelegate reject] reloadCollectionView:[OCMArg any] sections:[OCMArg any]]; + self.adapter.updatingDelegate = mockDelegate; + + id sectionController = [IGListSectionController new]; + [self.adapter reloadSectionController:sectionController]; + + [mockDelegate verify]; +} + @end diff --git a/Tests/IGListDiffSwiftTests.swift b/Tests/IGListDiffSwiftTests.swift index 381f6d42a..d22f47b8f 100644 --- a/Tests/IGListDiffSwiftTests.swift +++ b/Tests/IGListDiffSwiftTests.swift @@ -29,11 +29,9 @@ class SwiftClass: IGListDiffable { return NSNumber(value: id) } - func isEqual(_ object: IGListDiffable?) -> Bool { - if let object = object as? SwiftClass { - return id == object.id && value == object.value - } - return false + func isEqual(toDiffableObject object: IGListDiffable?) -> Bool { + guard let object = object as? SwiftClass else { return false } + return id == object.id && value == object.value } } @@ -47,7 +45,7 @@ class IGDiffingSwiftTests: XCTestCase { func testDiffingStrings() { let o: [NSString] = ["a", "b", "c"] let n: [NSString] = ["a", "c", "d"] - let result = IGListDiff(o as [IGListDiffable]?, n, .equality) + let result = IGListDiff(o, n, .equality) XCTAssertEqual(result.deletes, IndexSet(integer: 1)) XCTAssertEqual(result.inserts, IndexSet(integer: 2)) XCTAssertEqual(result.moves.count, 0) @@ -57,7 +55,7 @@ class IGDiffingSwiftTests: XCTestCase { func testDiffingNumbers() { let o: [NSNumber] = [0, 1, 2] let n: [NSNumber] = [0, 2, 4] - let result = IGListDiff(o as [IGListDiffable]?, n, .equality) + let result = IGListDiff(o, n, .equality) XCTAssertEqual(result.deletes, IndexSet(integer: 1)) XCTAssertEqual(result.inserts, IndexSet(integer: 2)) XCTAssertEqual(result.moves.count, 0) diff --git a/Tests/IGListDiffTests.m b/Tests/IGListDiffTests.m index 1e7763bfb..eb60c06fe 100644 --- a/Tests/IGListDiffTests.m +++ b/Tests/IGListDiffTests.m @@ -428,4 +428,9 @@ - (void)test_whenDiffing_withBatchUpdateResult_thatIndexPathsMatch { XCTAssertEqualObjects(sorted(result.inserts), expectedInserts); } +- (void)test_whenComparingDiffableObjects_withDefaultCategory_thatPointersAreAlwaysEqual { + NSObject *object = [NSObject new]; + XCTAssertTrue([object isEqualToDiffableObject:object]); +} + @end diff --git a/Tests/IGListObjectMapTests.m b/Tests/IGListSectionMapTests.m similarity index 90% rename from Tests/IGListObjectMapTests.m rename to Tests/IGListSectionMapTests.m index c19200bfc..9d210614b 100644 --- a/Tests/IGListObjectMapTests.m +++ b/Tests/IGListSectionMapTests.m @@ -82,4 +82,12 @@ - (void)test_whenEnumeratingMap_withStopFlagSet_thatEnumerationEndsEarly { XCTAssertEqual(counter, 2); } +- (void)test_whenAccessingOOBSection_thatNilIsReturned { + NSArray *objects = @[@0, @1, @2]; + NSArray *sectionControllers = @[@"a", @"b", @"c"]; + IGListSectionMap *map = [[IGListSectionMap alloc] initWithMapTable:[NSMapTable strongToStrongObjectsMapTable]]; + [map updateWithObjects:objects sectionControllers:sectionControllers]; + XCTAssertNil([map objectForSection:4]); +} + @end diff --git a/Tests/IGListSingleStoryboardItemControllerTests.m b/Tests/IGListSingleStoryboardItemControllerTests.m index 19d738457..0acd42d4c 100644 --- a/Tests/IGListSingleStoryboardItemControllerTests.m +++ b/Tests/IGListSingleStoryboardItemControllerTests.m @@ -11,7 +11,7 @@ #import "IGTestStoryboardCell.h" #import "IGTestSingleStoryboardItemDataSource.h" -#import "IGTestSingleStoryboardViewController.h" +#import "IGTestStoryboardViewController.h" #define genTestObject(k, v) [[IGTestObject alloc] initWithKey:k value:v] @@ -23,7 +23,7 @@ @interface IGListSingleStoryboardSectionControllerTests : XCTestCase @property (nonatomic, strong) IGListAdapter *adapter; @property (nonatomic, strong) IGListAdapterUpdater *updater; @property (nonatomic, strong) IGTestSingleStoryboardItemDataSource *dataSource; -@property (nonatomic, strong) IGTestSingleStoryboardViewController *viewController; +@property (nonatomic, strong) IGTestStoryboardViewController *viewController; @property (nonatomic, strong) UIWindow *window; @end diff --git a/Tests/Objects/IGListTestAdapterStoryboardDataSource.h b/Tests/Objects/IGListTestAdapterStoryboardDataSource.h new file mode 100644 index 000000000..772bb155c --- /dev/null +++ b/Tests/Objects/IGListTestAdapterStoryboardDataSource.h @@ -0,0 +1,21 @@ +/** + * Copyright (c) 2016-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +#import + +@interface IGListTestAdapterStoryboardDataSource : NSObject + +// array of numbers which is then passed to -[IGListTestSection setItems:] +@property (nonatomic, strong) NSArray *objects; + +@property (nonatomic, strong) UIView *backgroundView; + +@end diff --git a/Tests/Objects/IGListTestAdapterStoryboardDataSource.m b/Tests/Objects/IGListTestAdapterStoryboardDataSource.m new file mode 100644 index 000000000..ddf06ce97 --- /dev/null +++ b/Tests/Objects/IGListTestAdapterStoryboardDataSource.m @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2016-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "IGListTestAdapterStoryboardDataSource.h" + +#import + +#import "IGListTestStoryboardSection.h" + +@implementation IGListTestAdapterStoryboardDataSource + +- (NSArray *)objectsForListAdapter:(IGListAdapter *)listAdapter { + return self.objects; +} + +- (IGListSectionController *)listAdapter:(IGListAdapter *)listAdapter sectionControllerForObject:(id)object { + IGListTestStoryboardSection *list = [[IGListTestStoryboardSection alloc] init]; + return list; +} + +- (nullable UIView *)emptyViewForListAdapter:(IGListAdapter *)listAdapter { + return self.backgroundView; +} + +@end diff --git a/Tests/Objects/IGListTestStoryboardSection.h b/Tests/Objects/IGListTestStoryboardSection.h new file mode 100644 index 000000000..b84af0160 --- /dev/null +++ b/Tests/Objects/IGListTestStoryboardSection.h @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2016-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +#import +#import + +@interface IGListTestStoryboardSection : IGListSectionController + +@property (nonatomic, assign) NSInteger items; + +@end diff --git a/Tests/Objects/IGListTestStoryboardSection.m b/Tests/Objects/IGListTestStoryboardSection.m new file mode 100644 index 000000000..8992e204e --- /dev/null +++ b/Tests/Objects/IGListTestStoryboardSection.m @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2016-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "IGListTestStoryboardSection.h" +#import "IGTestStoryboardCell.h" + +@implementation IGListTestStoryboardSection + +- (NSInteger)numberOfItems { + return self.items; +} + +- (CGSize)sizeForItemAtIndex:(NSInteger)index { + return CGSizeMake(100, 45); +} + +- (UICollectionViewCell *)cellForItemAtIndex:(NSInteger)index { + return [self.collectionContext dequeueReusableCellFromStoryboardWithIdentifier:@"IGTestStoryboardCell" + forSectionController:self + atIndex:index]; +} + +- (void)didUpdateToObject:(id)object { + if ([object isKindOfClass:[NSNumber class]]) { + self.items = [object integerValue]; + } +} + +- (void)didSelectItemAtIndex:(NSInteger)index {} + +@end diff --git a/Tests/Objects/IGListTestUICollectionViewDataSource.m b/Tests/Objects/IGListTestUICollectionViewDataSource.m index 6773028be..d7faf41f3 100644 --- a/Tests/Objects/IGListTestUICollectionViewDataSource.m +++ b/Tests/Objects/IGListTestUICollectionViewDataSource.m @@ -25,7 +25,7 @@ + (instancetype)sectionWithObjects:(NSArray *)objects { return [NSString stringWithFormat:@"%zi", self.hash]; } -- (BOOL)isEqual:(id)object { +- (BOOL)isEqualToDiffableObject:(id)object { if (object == self) { return YES; } else if ([object isKindOfClass:IGSectionObject.class]) { diff --git a/Tests/Objects/IGTestNibSupplementaryView.h b/Tests/Objects/IGTestNibSupplementaryView.h new file mode 100644 index 000000000..939491419 --- /dev/null +++ b/Tests/Objects/IGTestNibSupplementaryView.h @@ -0,0 +1,18 @@ +/** + * Copyright (c) 2016-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +@interface IGTestNibSupplementaryView : UICollectionViewCell + +@property (nonatomic, weak) id delegate; + +@property (nonatomic, strong) IBOutlet UILabel *label; + +@end diff --git a/Source/Internal/NSIndexSet+PrettyDescription.h b/Tests/Objects/IGTestNibSupplementaryView.m similarity index 74% rename from Source/Internal/NSIndexSet+PrettyDescription.h rename to Tests/Objects/IGTestNibSupplementaryView.m index 5c9443277..b1aaddbb1 100644 --- a/Source/Internal/NSIndexSet+PrettyDescription.h +++ b/Tests/Objects/IGTestNibSupplementaryView.m @@ -7,10 +7,8 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#import +#import "IGTestNibSupplementaryView.h" -@interface NSIndexSet (PrettyDescription) - -- (NSString *)prettyDescription; +@implementation IGTestNibSupplementaryView @end diff --git a/Tests/Objects/IGTestSingleItemDataSource.m b/Tests/Objects/IGTestSingleItemDataSource.m index 21e124e47..6d5ea8c25 100644 --- a/Tests/Objects/IGTestSingleItemDataSource.m +++ b/Tests/Objects/IGTestSingleItemDataSource.m @@ -23,7 +23,7 @@ - (NSArray *)objectsForListAdapter:(IGListAdapter *)listAdapter { void (^configureBlock)(id, __kindof UICollectionViewCell *) = ^(IGTestObject *item, IGTestCell *cell) { cell.label.text = [item.value description]; }; - CGSize (^sizeBlock)(id) = ^CGSize(id collectionContext) { + CGSize (^sizeBlock)(id, id) = ^CGSize(IGTestObject *item, id collectionContext) { return CGSizeMake([collectionContext containerSize].width, 44); }; return [[IGListSingleSectionController alloc] initWithCellClass:IGTestCell.class diff --git a/Tests/Objects/IGTestSingleNibItemDataSource.m b/Tests/Objects/IGTestSingleNibItemDataSource.m index 1287d9fba..3c91fc85c 100644 --- a/Tests/Objects/IGTestSingleNibItemDataSource.m +++ b/Tests/Objects/IGTestSingleNibItemDataSource.m @@ -24,7 +24,7 @@ @implementation IGTestSingleNibItemDataSource void (^configureBlock)(id, __kindof UICollectionViewCell *) = ^(IGTestObject *item, IGTestCell *cell) { cell.label.text = [item.value description]; }; - CGSize (^sizeBlock)(id) = ^CGSize(id collectionContext) { + CGSize (^sizeBlock)(id, id) = ^CGSize(IGTestObject *item, id collectionContext) { return CGSizeMake([collectionContext containerSize].width, 44); }; return [[IGListSingleSectionController alloc] initWithNibName:@"IGTestNibCell" diff --git a/Tests/Objects/IGTestSingleStoryboardItemDataSource.m b/Tests/Objects/IGTestSingleStoryboardItemDataSource.m index fe19ef892..f1e12ac83 100644 --- a/Tests/Objects/IGTestSingleStoryboardItemDataSource.m +++ b/Tests/Objects/IGTestSingleStoryboardItemDataSource.m @@ -24,7 +24,7 @@ @implementation IGTestSingleStoryboardItemDataSource void (^configureBlock)(id, __kindof UICollectionViewCell *) = ^(IGTestObject *item, IGTestStoryboardCell *cell) { cell.label.text = [item.value description]; }; - CGSize (^sizeBlock)(id) = ^CGSize(id collectionContext) { + CGSize (^sizeBlock)(id, id) = ^CGSize(IGTestObject *item, id collectionContext) { return CGSizeMake([collectionContext containerSize].width, 44); }; return [[IGListSingleSectionController alloc] initWithStoryboardCellIdentifier:@"IGTestStoryboardCell" diff --git a/Tests/Objects/IGTestStoryboardSupplementarySource.h b/Tests/Objects/IGTestStoryboardSupplementarySource.h new file mode 100644 index 000000000..d860c7db0 --- /dev/null +++ b/Tests/Objects/IGTestStoryboardSupplementarySource.h @@ -0,0 +1,22 @@ +/** + * Copyright (c) 2016-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +#import + +@interface IGTestStoryboardSupplementarySource : NSObject + +@property (nonatomic, strong, readwrite) NSArray *supportedElementKinds; + +@property (nonatomic, weak) id collectionContext; + +@property (nonatomic, weak) IGListSectionController *sectionController; + +@end diff --git a/Tests/Objects/IGTestStoryboardSupplementarySource.m b/Tests/Objects/IGTestStoryboardSupplementarySource.m new file mode 100644 index 000000000..9e3956c6d --- /dev/null +++ b/Tests/Objects/IGTestStoryboardSupplementarySource.m @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2016-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "IGTestStoryboardSupplementarySource.h" +#import "IGTestStoryboardSupplementaryView.h" + +@implementation IGTestStoryboardSupplementarySource + +- (UICollectionReusableView *)viewForSupplementaryElementOfKind:(NSString *)elementKind + atIndex:(NSInteger)index { + IGTestStoryboardSupplementaryView *view = [self.collectionContext dequeueReusableSupplementaryViewFromStoryboardOfKind:elementKind + withIdentifier:@"IGTestStoryboardSupplementaryView" + forSectionController:self.sectionController + atIndex:index]; + view.label.text = @"Header"; + return view; +} + +- (CGSize)sizeForSupplementaryViewOfKind:(NSString *)elementKind atIndex:(NSInteger)index { + return CGSizeMake([self.collectionContext containerSize].width, 45); +} + +- (CGSize)estimatedSizeForSupplementaryViewOfKind:(NSString *)elementKind + atIndex:(NSInteger)index { + return CGSizeZero; +} + + +@end diff --git a/Tests/Objects/IGTestStoryboardSupplementaryView.h b/Tests/Objects/IGTestStoryboardSupplementaryView.h new file mode 100644 index 000000000..bd89806fb --- /dev/null +++ b/Tests/Objects/IGTestStoryboardSupplementaryView.h @@ -0,0 +1,16 @@ +/** + * Copyright (c) 2016-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +@interface IGTestStoryboardSupplementaryView : UICollectionReusableView + +@property (weak, nonatomic) IBOutlet UILabel *label; + +@end diff --git a/Tests/Objects/IGTestStoryboardSupplementaryView.m b/Tests/Objects/IGTestStoryboardSupplementaryView.m new file mode 100644 index 000000000..47187d296 --- /dev/null +++ b/Tests/Objects/IGTestStoryboardSupplementaryView.m @@ -0,0 +1,14 @@ +/** + * Copyright (c) 2016-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "IGTestStoryboardSupplementaryView.h" + +@implementation IGTestStoryboardSupplementaryView + +@end diff --git a/Tests/Objects/IGTestSingleStoryboardViewController.h b/Tests/Objects/IGTestStoryboardViewController.h similarity index 88% rename from Tests/Objects/IGTestSingleStoryboardViewController.h rename to Tests/Objects/IGTestStoryboardViewController.h index 85939fd78..c2c8f4100 100644 --- a/Tests/Objects/IGTestSingleStoryboardViewController.h +++ b/Tests/Objects/IGTestStoryboardViewController.h @@ -15,7 +15,7 @@ #import "IGTestObject.h" -@interface IGTestSingleStoryboardViewController : UIViewController +@interface IGTestStoryboardViewController : UIViewController @property (weak, nonatomic) IBOutlet IGListCollectionView *collectionView; diff --git a/Tests/Objects/IGTestSingleStoryboardViewController.m b/Tests/Objects/IGTestStoryboardViewController.m similarity index 63% rename from Tests/Objects/IGTestSingleStoryboardViewController.m rename to Tests/Objects/IGTestStoryboardViewController.m index 1ffead515..8cf49edc5 100644 --- a/Tests/Objects/IGTestSingleStoryboardViewController.m +++ b/Tests/Objects/IGTestStoryboardViewController.m @@ -7,16 +7,13 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#import "IGTestSingleStoryboardViewController.h" - -#import - +#import "IGTestStoryboardViewController.h" #import "IGTestStoryboardCell.h" -@interface IGTestSingleStoryboardViewController () +@interface IGTestStoryboardViewController () @end -@implementation IGTestSingleStoryboardViewController +@implementation IGTestStoryboardViewController @end diff --git a/Tests/Objects/IGTestSupplementarySource.h b/Tests/Objects/IGTestSupplementarySource.h index 68ed602e0..f6a005fdd 100644 --- a/Tests/Objects/IGTestSupplementarySource.h +++ b/Tests/Objects/IGTestSupplementarySource.h @@ -13,6 +13,8 @@ @interface IGTestSupplementarySource : NSObject +@property (nonatomic, assign) BOOL dequeueFromNib; + @property (nonatomic, strong, readwrite) NSArray *supportedElementKinds; @property (nonatomic, weak) id collectionContext; diff --git a/Tests/Objects/IGTestSupplementarySource.m b/Tests/Objects/IGTestSupplementarySource.m index fca3d0e2a..34f57e0da 100644 --- a/Tests/Objects/IGTestSupplementarySource.m +++ b/Tests/Objects/IGTestSupplementarySource.m @@ -9,16 +9,28 @@ #import "IGTestSupplementarySource.h" +#import "IGTestNibSupplementaryView.h" + @implementation IGTestSupplementarySource #pragma mark - IGListSupplementaryViewSource - (UICollectionReusableView *)viewForSupplementaryElementOfKind:(NSString *)elementKind atIndex:(NSInteger)index { - return [self.collectionContext dequeueReusableSupplementaryViewOfKind:elementKind - forSectionController:self.sectionController - class:[UICollectionReusableView class] - atIndex:index]; + if (self.dequeueFromNib) { + IGTestNibSupplementaryView *view = [self.collectionContext dequeueReusableSupplementaryViewOfKind:elementKind + forSectionController:self.sectionController + nibName:@"IGTestNibSupplementaryView" + bundle:[NSBundle bundleForClass:self.class] + atIndex:index]; + view.label.text = @"Foo bar baz"; + return view; + } else { + return [self.collectionContext dequeueReusableSupplementaryViewOfKind:elementKind + forSectionController:self.sectionController + class:[UICollectionReusableView class] + atIndex:index]; + } } - (CGSize)sizeForSupplementaryViewOfKind:(NSString *)elementKind atIndex:(NSInteger)index {