├── .github ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE.md ├── PULL_REQUEST_TEMPLATE.md ├── RELEASE_CHECKLIST.md └── workflows │ └── CI.yml ├── .gitignore ├── .slather.yml ├── .swiftlint.yml ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── Dangerfile ├── Examples ├── Examples-iOS │ ├── IGListKitExamples-UITests │ │ ├── DemosViewControllerUITests.swift │ │ ├── FeedViewController.swift │ │ ├── Info.plist │ │ ├── LoadMoreViewControllerUITests.swift │ │ ├── MixedDataViewControllerUITests.swift │ │ ├── SearchViewControllerUITests.swift │ │ └── UITestCase.swift │ ├── IGListKitExamples.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ ├── IGListKitExamples.xcscheme │ │ │ ├── IGListKitMessageExample.xcscheme │ │ │ └── IGListKitTodayExample.xcscheme │ ├── IGListKitExamples │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ │ └── AppIcon.appiconset │ │ │ │ ├── AppIcon.png │ │ │ │ └── Contents.json │ │ ├── Base.lproj │ │ │ └── LaunchScreen.storyboard │ │ ├── DelegateProtocols │ │ │ └── PostSectionControllerDelegate.swift │ │ ├── Extensions │ │ │ ├── UIActivityIndicatorView+Extension.swift │ │ │ └── UIColor+Extension.swift │ │ ├── IGListKitExamples.entitlements │ │ ├── Info.plist │ │ ├── Models │ │ │ ├── APIService.swift │ │ │ ├── ActivityItem.swift │ │ │ ├── FeedItem.swift │ │ │ ├── GridItem.swift │ │ │ ├── HorizontalCardsSection.swift │ │ │ ├── LoadingCellModel.swift │ │ │ ├── Month.swift │ │ │ ├── Post.h │ │ │ ├── Post.m │ │ │ ├── PostModel.swift │ │ │ ├── RemodelGeneratedModels │ │ │ │ ├── PersonModel.h │ │ │ │ ├── PersonModel.m │ │ │ │ └── PersonModel.value │ │ │ ├── SelectionModel.swift │ │ │ ├── SwipeActionSection.swift │ │ │ ├── User.swift │ │ │ └── ViewModels │ │ │ │ ├── DayViewModel.swift │ │ │ │ └── MonthTitleViewModel.swift │ │ ├── SectionControllers │ │ │ ├── DemoSectionController.swift │ │ │ ├── DisplaySectionController.swift │ │ │ ├── EmbeddedSectionController.swift │ │ │ ├── ExpandableSectionController.swift │ │ │ ├── FeedItemSectionController.swift │ │ │ ├── GridSectionController.swift │ │ │ ├── HorizontalSectionController.swift │ │ │ ├── LabelSectionController.swift │ │ │ ├── ListeningSectionController.swift │ │ │ ├── LoadingSectionController.swift │ │ │ ├── MonthSectionController.swift │ │ │ ├── PersonSectionController.h │ │ │ ├── PersonSectionController.m │ │ │ ├── PostSectionController.h │ │ │ ├── PostSectionController.m │ │ │ ├── PostSectionController.swift │ │ │ ├── RemoveSectionController.swift │ │ │ ├── ReorderableSectionController.swift │ │ │ ├── SearchSectionController.swift │ │ │ ├── SelfSizingSectionController.swift │ │ │ ├── StoryboardLabelSectionController.swift │ │ │ ├── UserSectionController.swift │ │ │ ├── With Composable Layout │ │ │ │ ├── ActivityComposableSectionController.swift │ │ │ │ ├── ExpandableComposableSectionController.swift │ │ │ │ ├── GridComposableSectionController.swift │ │ │ │ ├── HorizontalComposableSectionController.swift │ │ │ │ ├── SelectionComposableSectionController.swift │ │ │ │ ├── SwipeActionComposabelSectionController.swift │ │ │ │ └── UserComposableSectionController.swift │ │ │ └── WorkingRangeSectionController.swift │ │ ├── Storyboard │ │ │ └── Demo.storyboard │ │ ├── Systems │ │ │ └── IncrementAnnouncer.swift │ │ ├── ViewControllers │ │ │ ├── AnnouncingDepsViewController.swift │ │ │ ├── CalendarViewController.swift │ │ │ ├── CompositionLayoutViewController.swift │ │ │ ├── DemosViewController.swift │ │ │ ├── DiffTableViewController.swift │ │ │ ├── DisplayViewController.swift │ │ │ ├── EmptyViewController.swift │ │ │ ├── FeedViewController.swift │ │ │ ├── IGListKitExamples-Bridging-Header.h │ │ │ ├── LoadMoreViewController.swift │ │ │ ├── MixedDataViewController.swift │ │ │ ├── NestedAdapterViewController.swift │ │ │ ├── ObjcDemoViewController.h │ │ │ ├── ObjcDemoViewController.m │ │ │ ├── ObjcGeneratedModelDemoViewController.h │ │ │ ├── ObjcGeneratedModelDemoViewController.m │ │ │ ├── ReorderableViewController.swift │ │ │ ├── SearchViewController.swift │ │ │ ├── SelfSizingCellsViewController.swift │ │ │ ├── SingleSectionStoryboardViewController.swift │ │ │ ├── SingleSectionViewController.swift │ │ │ ├── StoryboardViewController.swift │ │ │ ├── SupplementaryViewController.swift │ │ │ └── WorkingRangeViewController.swift │ │ └── Views │ │ │ ├── CalendarDayCell.swift │ │ │ ├── CenterLabelCell.swift │ │ │ ├── CommentCell.h │ │ │ ├── CommentCell.m │ │ │ ├── CompositionLayoutCell.swift │ │ │ ├── DetailLabelCell.swift │ │ │ ├── EmbeddedCollectionViewCell.swift │ │ │ ├── FullWidthSelfSizingCell.swift │ │ │ ├── ImageCell.swift │ │ │ ├── InteractiveCell.h │ │ │ ├── InteractiveCell.m │ │ │ ├── LabelCell.swift │ │ │ ├── LoadingCell.swift │ │ │ ├── ManuallySelfSizingCell.swift │ │ │ ├── MonthTitleCell.swift │ │ │ ├── NibCell.swift │ │ │ ├── NibCell.xib │ │ │ ├── NibSelfSizingCell.swift │ │ │ ├── NibSelfSizingCell.xib │ │ │ ├── PersonCell.h │ │ │ ├── PersonCell.m │ │ │ ├── PhotoCell.h │ │ │ ├── PhotoCell.m │ │ │ ├── PostCell.swift │ │ │ ├── RemoveCell.swift │ │ │ ├── SearchCell.swift │ │ │ ├── SpinnerCell.swift │ │ │ ├── StoryboardCell.swift │ │ │ ├── UserFooterView.swift │ │ │ ├── UserFooterView.xib │ │ │ ├── UserHeaderView.swift │ │ │ ├── UserHeaderView.xib │ │ │ ├── UserInfoCell.h │ │ │ └── UserInfoCell.m │ ├── IGListKitMessageExample │ │ ├── Assets.xcassets │ │ │ ├── Contents.json │ │ │ └── iMessage App Icon.stickersiconset │ │ │ │ └── Contents.json │ │ ├── Info.plist │ │ └── MessagesViewController.swift │ ├── IGListKitTodayExample │ │ ├── Info.plist │ │ └── TodayViewController.swift │ └── LICENSE-examples.md ├── Examples-macOS │ ├── IGListKitExamples.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── IGListKitExamples.xcscheme │ ├── IGListKitExamples │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ │ └── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ ├── Base.lproj │ │ │ └── Main.storyboard │ │ ├── Data │ │ │ └── users.json │ │ ├── Helpers │ │ │ ├── IndexSet+Extensions.swift │ │ │ ├── Shuffle.swift │ │ │ └── UsersProvider.swift │ │ ├── Info.plist │ │ ├── Models │ │ │ └── User.swift │ │ ├── View │ │ │ ├── UserCollectionViewCell.swift │ │ │ └── UserCollectionViewCell.xib │ │ └── ViewControllers │ │ │ └── UsersViewController.swift │ └── LICENSE-examples.md └── Examples-tvOS │ ├── IGListKitExamples.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── IGListKitExamples.xcscheme │ ├── IGListKitExamples │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── App Icon & Top Shelf Image.brandassets │ │ │ ├── App Icon - Large.imagestack │ │ │ │ ├── Back.imagestacklayer │ │ │ │ │ ├── Content.imageset │ │ │ │ │ │ └── Contents.json │ │ │ │ │ └── Contents.json │ │ │ │ ├── Contents.json │ │ │ │ ├── Front.imagestacklayer │ │ │ │ │ ├── Content.imageset │ │ │ │ │ │ └── Contents.json │ │ │ │ │ └── Contents.json │ │ │ │ └── Middle.imagestacklayer │ │ │ │ │ ├── Content.imageset │ │ │ │ │ └── Contents.json │ │ │ │ │ └── Contents.json │ │ │ ├── App Icon - Small.imagestack │ │ │ │ ├── Back.imagestacklayer │ │ │ │ │ ├── Content.imageset │ │ │ │ │ │ └── Contents.json │ │ │ │ │ └── Contents.json │ │ │ │ ├── Contents.json │ │ │ │ ├── Front.imagestacklayer │ │ │ │ │ ├── Content.imageset │ │ │ │ │ │ └── Contents.json │ │ │ │ │ └── Contents.json │ │ │ │ └── Middle.imagestacklayer │ │ │ │ │ ├── Content.imageset │ │ │ │ │ └── Contents.json │ │ │ │ │ └── Contents.json │ │ │ ├── Contents.json │ │ │ ├── Top Shelf Image Wide.imageset │ │ │ │ └── Contents.json │ │ │ └── Top Shelf Image.imageset │ │ │ │ └── Contents.json │ │ ├── Contents.json │ │ └── LaunchImage.launchimage │ │ │ └── Contents.json │ ├── Info.plist │ ├── Models │ │ └── NSObject+IGListDiffable.swift │ ├── SectionControllers │ │ ├── CarouselSectionController.swift │ │ ├── DemoSectionController.swift │ │ ├── HorizontalSectionController.swift │ │ └── LabelSectionController.swift │ ├── ViewControllers │ │ ├── DemosViewController.swift │ │ └── NestedAdapterViewController.swift │ └── Views │ │ ├── CarouselCell.swift │ │ ├── CarouselCell.xib │ │ ├── DemoCell.swift │ │ ├── EmbeddedCollectionViewCell.swift │ │ └── LabelCell.swift │ └── LICENSE-examples.md ├── Gemfile ├── Guides ├── Best Practices and FAQ.md ├── Generating your models using remodel.md ├── Getting Started.md ├── IGListDiffable and Equality.md ├── Installation.md ├── Migration.md ├── Modeling and Binding.md ├── VISION.md ├── Working with Core Data.md └── Working with UICollectionView.md ├── IGListDiffKit.podspec ├── IGListKit.podspec ├── IGListKit.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcshareddata │ └── xcschemes │ ├── IGListKit-macOS.xcscheme │ ├── IGListKit-tvOS.xcscheme │ └── IGListKit.xcscheme ├── IGListSwiftKit.podspec ├── LICENSE.md ├── Package.swift ├── Podfile ├── README.md ├── README.zh.md ├── Resources ├── binding-flow.png ├── logo-animation.gif ├── logo.png ├── modeling-design.png ├── modeling-likes.gif ├── modeling-working.png ├── replace-iglistcollectionview.png └── workingrange.png ├── Source ├── IGListDiffKit │ ├── IGListAssert.h │ ├── IGListBatchUpdateData.h │ ├── IGListBatchUpdateData.mm │ ├── IGListCompatibility.h │ ├── IGListDiff.h │ ├── IGListDiff.mm │ ├── IGListDiffKit.h │ ├── IGListDiffable.h │ ├── IGListExperiments.h │ ├── IGListIndexPathResult.h │ ├── IGListIndexPathResult.m │ ├── IGListIndexSetResult.h │ ├── IGListIndexSetResult.m │ ├── IGListMacros.h │ ├── IGListMoveIndex.h │ ├── IGListMoveIndex.m │ ├── IGListMoveIndexPath.h │ ├── IGListMoveIndexPath.m │ ├── Internal │ │ ├── IGListIndexPathResultInternal.h │ │ ├── IGListIndexSetResultInternal.h │ │ ├── IGListMoveIndexInternal.h │ │ └── IGListMoveIndexPathInternal.h │ ├── NSNumber+IGListDiffable.h │ ├── NSNumber+IGListDiffable.m │ ├── NSString+IGListDiffable.h │ └── NSString+IGListDiffable.m ├── IGListKit │ ├── IGListAdapter.h │ ├── IGListAdapter.m │ ├── IGListAdapterDataSource.h │ ├── IGListAdapterDelegate.h │ ├── IGListAdapterDelegateAnnouncer.h │ ├── IGListAdapterDelegateAnnouncer.m │ ├── IGListAdapterMoveDelegate.h │ ├── IGListAdapterPerformanceDelegate.h │ ├── IGListAdapterUpdateListener.h │ ├── IGListAdapterUpdater.h │ ├── IGListAdapterUpdater.m │ ├── IGListAdapterUpdaterDelegate.h │ ├── IGListBatchContext.h │ ├── IGListBindable.h │ ├── IGListBindingSectionController.h │ ├── IGListBindingSectionController.m │ ├── IGListBindingSectionControllerDataSource.h │ ├── IGListBindingSectionControllerSelectionDelegate.h │ ├── IGListBindingSingleSectionController.h │ ├── IGListBindingSingleSectionController.m │ ├── IGListCollectionContext.h │ ├── IGListCollectionScrollingTraits.h │ ├── IGListCollectionView.h │ ├── IGListCollectionView.m │ ├── IGListCollectionViewDelegateLayout.h │ ├── IGListCollectionViewLayout.h │ ├── IGListCollectionViewLayout.mm │ ├── IGListCollectionViewLayoutCompatible.h │ ├── IGListCollectionViewLayoutInvalidationContext.h │ ├── IGListCollectionViewLayoutInvalidationContext.m │ ├── IGListDisplayDelegate.h │ ├── IGListGenericSectionController.h │ ├── IGListGenericSectionController.m │ ├── IGListKit.h │ ├── IGListReloadDataUpdater.h │ ├── IGListReloadDataUpdater.m │ ├── IGListScrollDelegate.h │ ├── IGListSectionController.h │ ├── IGListSectionController.m │ ├── IGListSingleSectionController.h │ ├── IGListSingleSectionController.m │ ├── IGListSupplementaryViewSource.h │ ├── IGListTransitionData.h │ ├── IGListTransitionData.m │ ├── IGListTransitionDelegate.h │ ├── IGListUpdatingDelegate.h │ ├── IGListWorkingRangeDelegate.h │ ├── Internal │ │ ├── IGListAdapter+DebugDescription.h │ │ ├── IGListAdapter+DebugDescription.m │ │ ├── IGListAdapter+UICollectionView.h │ │ ├── IGListAdapter+UICollectionView.m │ │ ├── IGListAdapterDelegateAnnouncerInternal.h │ │ ├── IGListAdapterInternal.h │ │ ├── IGListAdapterProxy.h │ │ ├── IGListAdapterProxy.m │ │ ├── IGListAdapterUpdater+DebugDescription.h │ │ ├── IGListAdapterUpdater+DebugDescription.m │ │ ├── IGListAdapterUpdaterHelpers.h │ │ ├── IGListAdapterUpdaterHelpers.m │ │ ├── IGListAdapterUpdaterInternal.h │ │ ├── IGListArrayUtilsInternal.h │ │ ├── IGListArrayUtilsInternal.m │ │ ├── IGListBatchUpdateData+DebugDescription.h │ │ ├── IGListBatchUpdateData+DebugDescription.m │ │ ├── IGListBatchUpdateState.h │ │ ├── IGListBatchUpdateTransaction.h │ │ ├── IGListBatchUpdateTransaction.m │ │ ├── IGListBindingSectionController+DebugDescription.h │ │ ├── IGListBindingSectionController+DebugDescription.m │ │ ├── IGListCollectionViewLayoutInternal.h │ │ ├── IGListDataSourceChangeTransaction.h │ │ ├── IGListDataSourceChangeTransaction.m │ │ ├── IGListDebugger.h │ │ ├── IGListDebugger.m │ │ ├── IGListDebuggingUtilities.h │ │ ├── IGListDebuggingUtilities.m │ │ ├── IGListDefaultExperiments.h │ │ ├── IGListDisplayHandler.h │ │ ├── IGListDisplayHandler.m │ │ ├── IGListItemUpdatesCollector.h │ │ ├── IGListItemUpdatesCollector.m │ │ ├── IGListPerformDiff.h │ │ ├── IGListPerformDiff.m │ │ ├── IGListReloadIndexPath.h │ │ ├── IGListReloadIndexPath.m │ │ ├── IGListReloadTransaction.h │ │ ├── IGListReloadTransaction.m │ │ ├── IGListSectionControllerInternal.h │ │ ├── IGListSectionMap+DebugDescription.h │ │ ├── IGListSectionMap+DebugDescription.m │ │ ├── IGListSectionMap.h │ │ ├── IGListSectionMap.m │ │ ├── IGListUpdateCoalescer.h │ │ ├── IGListUpdateCoalescer.m │ │ ├── IGListUpdateTransactable.h │ │ ├── IGListUpdateTransactionBuilder.h │ │ ├── IGListUpdateTransactionBuilder.m │ │ ├── IGListViewVisibilityTracker.h │ │ ├── IGListViewVisibilityTracker.m │ │ ├── IGListViewVisibilityTrackerInternal.h │ │ ├── IGListWorkingRangeHandler.h │ │ ├── IGListWorkingRangeHandler.mm │ │ ├── UICollectionView+DebugDescription.h │ │ ├── UICollectionView+DebugDescription.m │ │ ├── UICollectionView+IGListBatchUpdateData.h │ │ ├── UICollectionView+IGListBatchUpdateData.m │ │ ├── UICollectionViewLayout+InteractiveReordering.h │ │ ├── UICollectionViewLayout+InteractiveReordering.m │ │ ├── UIScrollView+IGListKit.h │ │ ├── UIScrollView+IGListKit.m │ │ └── UIViewController+IGListAdapterInternal.h │ ├── UIViewController+IGListAdapter.h │ └── UIViewController+IGListAdapter.m ├── IGListSwiftKit │ ├── IGListAdapter+Async.swift │ ├── IGListCollectionContext+Refinements.swift │ ├── IGListSingleSectionController+Refinements.swift │ ├── IGListSwiftKit.h │ ├── ListIdentifiable.swift │ └── ListValueSectionController.swift └── Info.plist ├── Tests ├── Assets │ ├── IGTestNibCell.xib │ ├── IGTestNibSupplementaryView.xib │ └── IGTestStoryboard.storyboard ├── IGListAdapterDelegateAnnouncerTests.m ├── IGListAdapterE2ETests.m ├── IGListAdapterProxyTests.m ├── IGListAdapterStoryboardTests.m ├── IGListAdapterTests.m ├── IGListAdapterUpdaterTests.m ├── IGListBatchUpdateDataTests.m ├── IGListBindingSectionControllerTests.m ├── IGListBindingSingleSectionControllerTests.m ├── IGListCollectionScrollingTraitsTests.m ├── IGListCollectionViewLayoutTests.m ├── IGListCollectionViewTests.m ├── IGListContentInsetTests.m ├── IGListDebugDescriptionTests.m ├── IGListDebuggerTests.m ├── IGListDiffDescriptionStringTests.m ├── IGListDiffResultTests.m ├── IGListDiffSwiftTests.swift ├── IGListDiffTests.h ├── IGListDiffTests.m ├── IGListDisplayHandlerTests.m ├── IGListGenericSectionControllerTests.m ├── IGListInteractiveMovingTests.m ├── IGListKitTests-Bridging-Header.h ├── IGListReloadDataUpdaterTests.m ├── IGListSectionControllerTests.m ├── IGListSectionMapTests.m ├── IGListSingleNibItemControllerTests.m ├── IGListSingleSectionControllerTests.m ├── IGListSingleStoryboardItemControllerTests.m ├── IGListTestCase.h ├── IGListTestCase.m ├── IGListTestHelpers.h ├── IGListTransactionTests.m ├── IGListViewVisibilityTrackerTests.m ├── IGListWorkingRangeHandlerTests.m ├── Info.plist ├── Objects │ ├── IGLayoutTestDataSource.h │ ├── IGLayoutTestDataSource.m │ ├── IGLayoutTestItem.h │ ├── IGLayoutTestItem.m │ ├── IGLayoutTestSection.h │ ├── IGLayoutTestSection.m │ ├── IGListAdapterUpdateTester.h │ ├── IGListAdapterUpdateTester.m │ ├── IGListTestAdapterDataSource.h │ ├── IGListTestAdapterDataSource.m │ ├── IGListTestAdapterHorizontalDataSource.h │ ├── IGListTestAdapterHorizontalDataSource.m │ ├── IGListTestAdapterReorderingDataSource.h │ ├── IGListTestAdapterReorderingDataSource.m │ ├── IGListTestAdapterStoryboardDataSource.h │ ├── IGListTestAdapterStoryboardDataSource.m │ ├── IGListTestCollectionViewLayout.h │ ├── IGListTestCollectionViewLayout.m │ ├── IGListTestContainerSizeSection.h │ ├── IGListTestContainerSizeSection.m │ ├── IGListTestHorizontalSection.h │ ├── IGListTestHorizontalSection.m │ ├── IGListTestOffsettingLayout.h │ ├── IGListTestOffsettingLayout.m │ ├── IGListTestSection.h │ ├── IGListTestSection.m │ ├── IGListTestStoryboardSection.h │ ├── IGListTestStoryboardSection.m │ ├── IGListTestUICollectionViewDataSource.h │ ├── IGListTestUICollectionViewDataSource.m │ ├── IGTestBindingSingleItemDataSource.h │ ├── IGTestBindingSingleItemDataSource.m │ ├── IGTestBindingWithoutDeselectionDelegate.h │ ├── IGTestBindingWithoutDeselectionDelegate.m │ ├── IGTestCell.h │ ├── IGTestCell.m │ ├── IGTestDelegateController.h │ ├── IGTestDelegateController.m │ ├── IGTestDelegateDataSource.h │ ├── IGTestDelegateDataSource.m │ ├── IGTestDiffingDataSource.h │ ├── IGTestDiffingDataSource.m │ ├── IGTestDiffingObject.h │ ├── IGTestDiffingObject.m │ ├── IGTestDiffingSectionController.h │ ├── IGTestDiffingSectionController.m │ ├── IGTestInvalidateLayoutDataSource.h │ ├── IGTestInvalidateLayoutDataSource.m │ ├── IGTestInvalidateLayoutObject.h │ ├── IGTestInvalidateLayoutObject.m │ ├── IGTestInvalidateLayoutSectionController.h │ ├── IGTestInvalidateLayoutSectionController.m │ ├── IGTestNibSupplementaryView.h │ ├── IGTestNibSupplementaryView.m │ ├── IGTestNumberBindableCell.h │ ├── IGTestNumberBindableCell.m │ ├── IGTestObject.h │ ├── IGTestObject.m │ ├── IGTestReorderableSection.h │ ├── IGTestReorderableSection.m │ ├── IGTestSingleItemDataSource.h │ ├── IGTestSingleItemDataSource.m │ ├── IGTestSingleNibItemDataSource.h │ ├── IGTestSingleNibItemDataSource.m │ ├── IGTestSingleStoryboardItemDataSource.h │ ├── IGTestSingleStoryboardItemDataSource.m │ ├── IGTestSingleWithoutDeselectionDelegate.h │ ├── IGTestSingleWithoutDeselectionDelegate.m │ ├── IGTestStoryboardCell.h │ ├── IGTestStoryboardCell.m │ ├── IGTestStoryboardSupplementarySource.h │ ├── IGTestStoryboardSupplementarySource.m │ ├── IGTestStoryboardSupplementaryView.h │ ├── IGTestStoryboardSupplementaryView.m │ ├── IGTestStoryboardViewController.h │ ├── IGTestStoryboardViewController.m │ ├── IGTestStringBindableCell.h │ ├── IGTestStringBindableCell.m │ ├── IGTestSupplementarySource.h │ └── IGTestSupplementarySource.m └── UIViewControllerIGListAdapterTests.m ├── docs ├── Classes.html ├── Classes │ ├── IGListAdapter.html │ ├── IGListAdapterUpdater.html │ ├── IGListBatchUpdateData.html │ ├── IGListBindingSectionController.html │ ├── IGListBindingSingleSectionController.html │ ├── IGListCollectionView.html │ ├── IGListCollectionViewLayout.html │ ├── IGListGenericSectionController.html │ ├── IGListIndexPathResult.html │ ├── IGListIndexSetResult.html │ ├── IGListMoveIndex.html │ ├── IGListMoveIndexPath.html │ ├── IGListSectionController.html │ ├── IGListSingleSectionController.html │ └── IGListTransitionData.html ├── Constants.html ├── Enums.html ├── Enums │ ├── IGListAdapterUpdateType.html │ ├── IGListDiffOption.html │ └── IGListExperiment.html ├── Functions.html ├── Guides.html ├── Protocols.html ├── Protocols │ ├── IGListAdapterDataSource.html │ ├── IGListAdapterDelegate.html │ ├── IGListAdapterMoveDelegate.html │ ├── IGListAdapterPerformanceDelegate.html │ ├── IGListAdapterUpdateListener.html │ ├── IGListAdapterUpdaterDelegate.html │ ├── IGListBatchContext.html │ ├── IGListBindable.html │ ├── IGListBindingSectionControllerDataSource.html │ ├── IGListBindingSectionControllerSelectionDelegate.html │ ├── IGListCollectionContext.html │ ├── IGListCollectionViewDelegateLayout.html │ ├── IGListCollectionViewLayoutCompatible.html │ ├── IGListDiffable.html │ ├── IGListDisplayDelegate.html │ ├── IGListScrollDelegate.html │ ├── IGListSingleSectionControllerDelegate.html │ ├── IGListSupplementaryViewSource.html │ ├── IGListTransitionDelegate.html │ ├── IGListUpdatingDelegate.html │ └── IGListWorkingRangeDelegate.html ├── Structs.html ├── Structs │ └── IGListCollectionScrollingTraits.html ├── Type Definitions.html ├── Type Definitions │ ├── IGListCollectionScrollingTraits.html │ └── IGListCollectionScrollingTraits │ │ └── IGListCollectionScrollingTraits.html ├── badge.svg ├── best-practices-and-faq.html ├── css │ ├── highlight.css │ └── jazzy.css ├── generating-your-models-using-remodel.html ├── getting-started.html ├── iglistdiffable-and-equality.html ├── img │ ├── carat.png │ ├── dash.png │ ├── gh.png │ └── spinner.gif ├── index.html ├── installation.html ├── js │ ├── jazzy.js │ ├── jazzy.search.js │ ├── jquery.min.js │ ├── lunr.min.js │ └── typeahead.jquery.js ├── migration.html ├── modeling-and-binding.html ├── search.json ├── undocumented.json ├── vision.html ├── working-with-core-data.html └── working-with-uicollectionview.html ├── remodel-plugin ├── features │ └── iglistdiffable.feature └── src │ ├── __tests__ │ └── plugins │ │ └── iglistdiffable-test.ts │ └── plugins │ ├── iglistdiffable-utils.ts │ └── iglistdiffable.ts ├── scripts ├── build_docs.sh ├── generate_spm_sources_layout.sh ├── lint.sh └── version.sh └── spm └── Sources ├── IGListDiffKit ├── IGListBatchUpdateData.mm ├── IGListDiff.mm ├── IGListIndexPathResult.m ├── IGListIndexPathResultInternal.h ├── IGListIndexSetResult.m ├── IGListIndexSetResultInternal.h ├── IGListMoveIndex.m ├── IGListMoveIndexInternal.h ├── IGListMoveIndexPath.m ├── IGListMoveIndexPathInternal.h ├── NSNumber+IGListDiffable.m ├── NSString+IGListDiffable.m └── include │ ├── IGListAssert.h │ ├── IGListBatchUpdateData.h │ ├── IGListCompatibility.h │ ├── IGListDiff.h │ ├── IGListDiffKit.h │ ├── IGListDiffable.h │ ├── IGListExperiments.h │ ├── IGListIndexPathResult.h │ ├── IGListIndexSetResult.h │ ├── IGListMacros.h │ ├── IGListMoveIndex.h │ ├── IGListMoveIndexPath.h │ ├── NSNumber+IGListDiffable.h │ └── NSString+IGListDiffable.h ├── IGListKit ├── IGListAdapter+DebugDescription.h ├── IGListAdapter+DebugDescription.m ├── IGListAdapter+UICollectionView.h ├── IGListAdapter+UICollectionView.m ├── IGListAdapter.m ├── IGListAdapterDelegateAnnouncer.m ├── IGListAdapterDelegateAnnouncerInternal.h ├── IGListAdapterInternal.h ├── IGListAdapterProxy.h ├── IGListAdapterProxy.m ├── IGListAdapterUpdater+DebugDescription.h ├── IGListAdapterUpdater+DebugDescription.m ├── IGListAdapterUpdater.m ├── IGListAdapterUpdaterHelpers.h ├── IGListAdapterUpdaterHelpers.m ├── IGListAdapterUpdaterInternal.h ├── IGListArrayUtilsInternal.h ├── IGListArrayUtilsInternal.m ├── IGListBatchUpdateData+DebugDescription.h ├── IGListBatchUpdateData+DebugDescription.m ├── IGListBatchUpdateState.h ├── IGListBatchUpdateTransaction.h ├── IGListBatchUpdateTransaction.m ├── IGListBindingSectionController+DebugDescription.h ├── IGListBindingSectionController+DebugDescription.m ├── IGListBindingSectionController.m ├── IGListBindingSingleSectionController.m ├── IGListCollectionView.m ├── IGListCollectionViewLayout.mm ├── IGListCollectionViewLayoutInternal.h ├── IGListCollectionViewLayoutInvalidationContext.m ├── IGListDataSourceChangeTransaction.h ├── IGListDataSourceChangeTransaction.m ├── IGListDebugger.h ├── IGListDebugger.m ├── IGListDebuggingUtilities.h ├── IGListDebuggingUtilities.m ├── IGListDefaultExperiments.h ├── IGListDisplayHandler.h ├── IGListDisplayHandler.m ├── IGListGenericSectionController.m ├── IGListIndexPathResultInternal.h ├── IGListIndexSetResultInternal.h ├── IGListItemUpdatesCollector.h ├── IGListItemUpdatesCollector.m ├── IGListMoveIndexInternal.h ├── IGListMoveIndexPathInternal.h ├── IGListPerformDiff.h ├── IGListPerformDiff.m ├── IGListReloadDataUpdater.m ├── IGListReloadIndexPath.h ├── IGListReloadIndexPath.m ├── IGListReloadTransaction.h ├── IGListReloadTransaction.m ├── IGListSectionController.m ├── IGListSectionControllerInternal.h ├── IGListSectionMap+DebugDescription.h ├── IGListSectionMap+DebugDescription.m ├── IGListSectionMap.h ├── IGListSectionMap.m ├── IGListSingleSectionController.m ├── IGListTransitionData.m ├── IGListUpdateCoalescer.h ├── IGListUpdateCoalescer.m ├── IGListUpdateTransactable.h ├── IGListUpdateTransactionBuilder.h ├── IGListUpdateTransactionBuilder.m ├── IGListViewVisibilityTracker.h ├── IGListViewVisibilityTracker.m ├── IGListViewVisibilityTrackerInternal.h ├── IGListWorkingRangeHandler.h ├── IGListWorkingRangeHandler.mm ├── UICollectionView+DebugDescription.h ├── UICollectionView+DebugDescription.m ├── UICollectionView+IGListBatchUpdateData.h ├── UICollectionView+IGListBatchUpdateData.m ├── UICollectionViewLayout+InteractiveReordering.h ├── UICollectionViewLayout+InteractiveReordering.m ├── UIScrollView+IGListKit.h ├── UIScrollView+IGListKit.m ├── UIViewController+IGListAdapter.m ├── UIViewController+IGListAdapterInternal.h └── include │ ├── IGListAdapter.h │ ├── IGListAdapterDataSource.h │ ├── IGListAdapterDelegate.h │ ├── IGListAdapterDelegateAnnouncer.h │ ├── IGListAdapterMoveDelegate.h │ ├── IGListAdapterPerformanceDelegate.h │ ├── IGListAdapterUpdateListener.h │ ├── IGListAdapterUpdater.h │ ├── IGListAdapterUpdaterDelegate.h │ ├── IGListBatchContext.h │ ├── IGListBindable.h │ ├── IGListBindingSectionController.h │ ├── IGListBindingSectionControllerDataSource.h │ ├── IGListBindingSectionControllerSelectionDelegate.h │ ├── IGListBindingSingleSectionController.h │ ├── IGListCollectionContext.h │ ├── IGListCollectionScrollingTraits.h │ ├── IGListCollectionView.h │ ├── IGListCollectionViewDelegateLayout.h │ ├── IGListCollectionViewLayout.h │ ├── IGListCollectionViewLayoutCompatible.h │ ├── IGListCollectionViewLayoutInvalidationContext.h │ ├── IGListDisplayDelegate.h │ ├── IGListGenericSectionController.h │ ├── IGListKit.h │ ├── IGListReloadDataUpdater.h │ ├── IGListScrollDelegate.h │ ├── IGListSectionController.h │ ├── IGListSingleSectionController.h │ ├── IGListSupplementaryViewSource.h │ ├── IGListTransitionData.h │ ├── IGListTransitionDelegate.h │ ├── IGListUpdatingDelegate.h │ ├── IGListWorkingRangeDelegate.h │ └── UIViewController+IGListAdapter.h └── IGListSwiftKit ├── IGListAdapter+Async.swift ├── IGListCollectionContext+Refinements.swift ├── IGListSingleSectionController+Refinements.swift ├── ListIdentifiable.swift └── ListValueSectionController.swift /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## New issue checklist 2 | 3 | - [ ] I have reviewed the [`README`](https://github.com/Instagram/IGListKit/blob/main/README.md) and [documentation](http://instagram.github.io/IGListKit) 4 | - [ ] I have searched [existing issues](https://github.com/Instagram/IGListKit/issues) and this is not a duplicate 5 | - [ ] I have attempted to reproduce the issue and include an example project. 6 | 7 | ### General information 8 | 9 | - `IGListKit` version: 10 | - iOS version(s): 11 | - CocoaPods/Carthage version: 12 | - Xcode version: 13 | - Devices/Simulators affected: 14 | - Reproducible in the demo project? (Yes/No): 15 | - Related issues: 16 | 17 | ### Debug information 18 | 19 | ```bash 20 | # Please include debug logs using the following lldb command: 21 | po [IGListDebugger dump] 22 | ``` 23 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Changes in this pull request 2 | 3 | Issue fixed: # 4 | 5 | ### Checklist 6 | 7 | - [ ] All tests pass. Demo project builds and runs. 8 | - [ ] I added tests, an experiment, or detailed why my change isn't tested. 9 | - [ ] I added an entry to the `CHANGELOG.md` for any breaking changes, enhancements, or bug fixes. 10 | - [ ] I have reviewed the [contributing guide](https://github.com/Instagram/IGListKit/blob/main/.github/CONTRIBUTING.md) 11 | -------------------------------------------------------------------------------- /.github/RELEASE_CHECKLIST.md: -------------------------------------------------------------------------------- 1 | # Release Checklist 2 | 3 | Here are the steps for creating and publishing a new release for `IGListKit`. 4 | 5 | - Final review and update of header docs and guides 6 | - Final review of changelog 7 | - Regenerate docs 8 | - Update pod spec version 9 | - Update xcodeproj version 10 | - Run `pod install` on all examples (**must happen on FB internal** because of sync issues) 11 | - Merge `main` into `stable` via cmd-line and push 12 | - Confirm `stable` is `0|0` [ahead/behind](https://github.com/Instagram/IGListKit/branches) 13 | - Create [GitHub release](https://github.com/Instagram/IGListKit/releases) from `stable` 14 | - Paste changelog into GH release notes 15 | - Publish GitHub release 16 | - Run `pod lib lint` 17 | - Push updated podspec: `pod trunk push IGListKit.podspec` 18 | - Verify new release on [CocoaPods](https://cocoapods.org/pods/IGListKit) 19 | - Tweet all the tweets 20 | -------------------------------------------------------------------------------- /.slather.yml: -------------------------------------------------------------------------------- 1 | ci_service: github 2 | coverage_service: coveralls 3 | xcodeproj: IGListKit.xcodeproj 4 | workspace: IGListKit.xcworkspace 5 | scheme: IGListKit 6 | source_directory: Source 7 | ignore: 8 | - ../**/*/Xcode* 9 | - Tests/* 10 | -------------------------------------------------------------------------------- /.swiftlint.yml: -------------------------------------------------------------------------------- 1 | included: 2 | - Examples 3 | - Source/IGListSwiftKit 4 | 5 | excluded: 6 | - Pods 7 | 8 | opt_in_rules: 9 | - empty_count 10 | - number_separator 11 | - operator_usage_whitespace 12 | - sorted_imports 13 | - vertical_parameter_alignment_on_call 14 | - overridden_super_call 15 | 16 | disabled_rules: 17 | - force_unwrapping 18 | - comma 19 | - line_length 20 | 21 | force_cast: warning 22 | force_try: warning 23 | 24 | weak_delegate: error 25 | 26 | type_body_length: 27 | warning: 300 28 | error: 400 29 | 30 | file_length: 31 | warning: 500 32 | error: 1200 33 | 34 | type_name: 35 | min_length: 4 36 | max_length: 37 | warning: 40 38 | error: 50 39 | excluded: iPhone 40 | 41 | identifier_name: 42 | min_length: 43 | error: 4 44 | excluded: 45 | - id 46 | - url 47 | - URL 48 | - pk 49 | - day 50 | - map 51 | - row 52 | - nib 53 | - GlobalAPIKey 54 | - to 55 | - obj 56 | - str 57 | - set 58 | 59 | reporter: "xcode" # reporter type (xcode, json, csv, checkstyle, junit, html, emoji) 60 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples-UITests/Info.plist: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 3 | <plist version="1.0"> 4 | <dict> 5 | <key>CFBundleDevelopmentRegion</key> 6 | <string>$(DEVELOPMENT_LANGUAGE)</string> 7 | <key>CFBundleExecutable</key> 8 | <string>$(EXECUTABLE_NAME)</string> 9 | <key>CFBundleIdentifier</key> 10 | <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> 11 | <key>CFBundleInfoDictionaryVersion</key> 12 | <string>6.0</string> 13 | <key>CFBundleName</key> 14 | <string>$(PRODUCT_NAME)</string> 15 | <key>CFBundlePackageType</key> 16 | <string>BNDL</string> 17 | <key>CFBundleShortVersionString</key> 18 | <string>1.0</string> 19 | <key>CFBundleVersion</key> 20 | <string>1</string> 21 | </dict> 22 | </plist> 23 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples-UITests/LoadMoreViewControllerUITests.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import XCTest 9 | 10 | final class LoadMoreViewControllerUITests: UITestCase { 11 | 12 | func test_whenScrollingToTheBottom_thatNewItemsAreLoaded() { 13 | let collectionViews = XCUIApplication().collectionViews 14 | collectionViews.cells.staticTexts["Tail Loading"].tap() 15 | 16 | // Swipe up until the last item in the list is on-screen 17 | var numberOfTries = 0 18 | let lastElem = collectionViews.cells.staticTexts["15"] 19 | while !lastElem.isHittable { 20 | collectionViews.element.swipeUp() 21 | numberOfTries += 1 22 | if numberOfTries >= 10 { 23 | break 24 | } 25 | } 26 | 27 | // Wait for the following item to be loaded asynchronously 28 | let newlyLoadedElement = collectionViews.cells.staticTexts["16"] 29 | waitToAppear(element: newlyLoadedElement, timeout: 30.0) 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <Workspace 3 | version = "1.0"> 4 | <FileRef 5 | location = "self:IGListKitExamples.xcodeproj"> 6 | </FileRef> 7 | </Workspace> 8 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/Assets.xcassets/AppIcon.appiconset/AppIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Instagram/IGListKit/01bd505d8b89b55fc3938fc5ce4a9f57a7a92f81/Examples/Examples-iOS/IGListKitExamples/Assets.xcassets/AppIcon.appiconset/AppIcon.png -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "AppIcon.png", 5 | "idiom" : "universal", 6 | "platform" : "ios", 7 | "size" : "1024x1024" 8 | } 9 | ], 10 | "info" : { 11 | "author" : "xcode", 12 | "version" : 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/DelegateProtocols/PostSectionControllerDelegate.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import UIKit 9 | 10 | /// To allow communication between PostSectionController and FeedViewController 11 | protocol PostSectionControllerDelegate: AnyObject { 12 | func postSectionController(_ sectionController: PostSectionController, didSelectOptionsFor post: Post, from sourceView: UIView) 13 | } 14 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/Extensions/UIActivityIndicatorView+Extension.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import UIKit 9 | 10 | extension UIActivityIndicatorView { 11 | 12 | class var defaultStyle: UIActivityIndicatorView.Style { 13 | if #available(iOS 13.0, *) { 14 | return .medium 15 | } else { 16 | return .gray 17 | } 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/IGListKitExamples.entitlements: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 3 | <plist version="1.0"> 4 | <dict> 5 | <key>com.apple.security.app-sandbox</key> 6 | <true/> 7 | <key>com.apple.security.network.client</key> 8 | <true/> 9 | </dict> 10 | </plist> 11 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/Models/ActivityItem.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import IGListKit 9 | 10 | final class ActivityItem: ListDiffable { 11 | 12 | let bodyText: String 13 | let header: String? 14 | let footer: String? 15 | 16 | init(bodyText: String, header: String? = nil, footer: String? = nil) { 17 | self.bodyText = bodyText 18 | self.header = header 19 | self.footer = footer 20 | } 21 | 22 | // MARK: ListDiffable 23 | 24 | func diffIdentifier() -> NSObjectProtocol { 25 | return bodyText as NSObjectProtocol 26 | } 27 | 28 | func isEqual(toDiffableObject object: ListDiffable?) -> Bool { 29 | guard self !== object else { return true } 30 | guard let object = object as? ActivityItem else { return false } 31 | return bodyText == object.bodyText 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/Models/FeedItem.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import IGListKit 9 | 10 | final class FeedItem: ListDiffable { 11 | 12 | let pk: Int 13 | let user: User 14 | let comments: [String] 15 | 16 | init(pk: Int, user: User, comments: [String]) { 17 | self.pk = pk 18 | self.user = user 19 | self.comments = comments 20 | } 21 | 22 | // MARK: ListDiffable 23 | 24 | func diffIdentifier() -> NSObjectProtocol { 25 | return pk as NSObjectProtocol 26 | } 27 | 28 | func isEqual(toDiffableObject object: ListDiffable?) -> Bool { 29 | guard self !== object else { return true } 30 | guard let object = object as? FeedItem else { return false } 31 | return user.isEqual(toDiffableObject: object.user) && comments == object.comments 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/Models/GridItem.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import IGListKit 9 | import Foundation 10 | 11 | final class GridItem: NSObject { 12 | 13 | let color: UIColor 14 | let itemCount: Int 15 | 16 | var items: [String] = [] 17 | 18 | init(color: UIColor, itemCount: Int) { 19 | self.color = color 20 | self.itemCount = itemCount 21 | 22 | super.init() 23 | 24 | self.items = computeItems() 25 | } 26 | 27 | private func computeItems() -> [String] { 28 | return [Int](1...itemCount).map { 29 | String(describing: $0) 30 | } 31 | } 32 | } 33 | 34 | extension GridItem: ListDiffable { 35 | 36 | func diffIdentifier() -> NSObjectProtocol { 37 | return self 38 | } 39 | 40 | func isEqual(toDiffableObject object: ListDiffable?) -> Bool { 41 | return self === object ? true : self.isEqual(object) 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/Models/HorizontalCardsSection.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import IGListKit 9 | import Foundation 10 | 11 | final class HorizontalCardsSection: NSObject { 12 | 13 | let cardCount: Int 14 | private(set) var items: [String] = [] 15 | 16 | init(cardCount: Int) { 17 | self.cardCount = cardCount 18 | super.init() 19 | self.items = computeItems() 20 | } 21 | 22 | private func computeItems() -> [String] { 23 | return [Int](1...cardCount).map { 24 | String(describing: $0) 25 | } 26 | } 27 | } 28 | 29 | extension HorizontalCardsSection: ListDiffable { 30 | 31 | func diffIdentifier() -> NSObjectProtocol { 32 | return self 33 | } 34 | 35 | func isEqual(toDiffableObject object: ListDiffable?) -> Bool { 36 | return self === object ? true : self.isEqual(object) 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/Models/LoadingCellModel.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import UIKit 9 | import IGListKit 10 | 11 | final class LoadingCellModel { 12 | let identifier = "loading-cell" 13 | } 14 | 15 | // MARK: - ListDiffable Implementation 16 | 17 | // Even simple models like this loading indicator need to conform to ListDiffable 18 | // in order to be used with IGListKit 19 | extension LoadingCellModel: ListDiffable { 20 | 21 | // The diffIdentifier uniquely identifies this object 22 | // For a singleton loading indicator, a static string ID is sufficient 23 | func diffIdentifier() -> any NSObjectProtocol { 24 | return self.identifier as NSObjectProtocol 25 | } 26 | 27 | // isEqual compares properties that affect the visual representation 28 | // For this simple case, comparing identifiers is enough 29 | func isEqual(toDiffableObject object: (any ListDiffable)?) -> Bool { 30 | guard let object = object as? LoadingCellModel else { return false } 31 | return self.identifier == object.identifier 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/Models/Month.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import Foundation 9 | import IGListKit 10 | 11 | final class Month { 12 | 13 | let name: String 14 | let days: Int 15 | 16 | // day int mapped to an array of appointment names 17 | let appointments: [Int: [NSString]] 18 | 19 | init(name: String, days: Int, appointments: [Int: [NSString]]) { 20 | self.name = name 21 | self.days = days 22 | self.appointments = appointments 23 | } 24 | 25 | } 26 | 27 | extension Month: ListDiffable { 28 | 29 | func diffIdentifier() -> NSObjectProtocol { 30 | return name as NSObjectProtocol 31 | } 32 | 33 | func isEqual(toDiffableObject object: ListDiffable?) -> Bool { 34 | return true 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/Models/Post.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | @import IGListDiffKit; 11 | 12 | @interface Post : NSObject <IGListDiffable> 13 | 14 | @property (nonatomic, strong, readonly) NSString *username; 15 | @property (nonatomic, strong, readonly) NSArray<NSString *> *comments; 16 | 17 | - (instancetype)initWithUsername:(NSString *)username 18 | comments:(NSArray<NSString *> *)comments NS_DESIGNATED_INITIALIZER; 19 | 20 | - (instancetype)init NS_UNAVAILABLE; 21 | + (instancetype)new NS_UNAVAILABLE; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/Models/Post.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "Post.h" 9 | 10 | @implementation Post 11 | 12 | - (instancetype)initWithUsername:(NSString *)username 13 | comments:(NSArray<NSString *> *)comments { 14 | if (self = [super init]) { 15 | _username = [username copy]; 16 | _comments = [comments copy]; 17 | } 18 | return self; 19 | } 20 | 21 | #pragma mark - IGListDiffable 22 | 23 | - (id<NSObject>)diffIdentifier { 24 | return self; 25 | } 26 | 27 | - (BOOL)isEqualToDiffableObject:(id)object { 28 | // since the diff identifier returns self, object should only be compared with same instance 29 | return self == object; 30 | } 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/Models/RemodelGeneratedModels/PersonModel.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | /** 9 | * This file is generated using the remodel generation script. 10 | * The name of the input file is PersonModel.value 11 | */ 12 | 13 | #import <Foundation/Foundation.h> 14 | 15 | @import IGListDiffKit; 16 | 17 | @interface PersonModel : NSObject <IGListDiffable, NSCopying> 18 | 19 | @property (nonatomic, readonly, copy) NSString *firstName; 20 | @property (nonatomic, readonly, copy) NSString *lastName; 21 | @property (nonatomic, readonly, copy) NSString *uniqueId; 22 | 23 | + (instancetype)new NS_UNAVAILABLE; 24 | 25 | - (instancetype)init NS_UNAVAILABLE; 26 | 27 | - (instancetype)initWithFirstName:(NSString *)firstName lastName:(NSString *)lastName uniqueId:(NSString *)uniqueId NS_DESIGNATED_INITIALIZER; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/Models/RemodelGeneratedModels/PersonModel.value: -------------------------------------------------------------------------------- 1 | PersonModel includes(IGListDiffable) { 2 | NSString *firstName 3 | NSString *lastName 4 | %diffIdentifier 5 | NSString *uniqueId 6 | } -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/Models/SelectionModel.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import IGListKit 9 | 10 | enum SelectionModelType: Int { 11 | case none, fullWidth, nib 12 | } 13 | 14 | final class SelectionModel: NSObject { 15 | 16 | let options: [String] 17 | let type: SelectionModelType 18 | 19 | init(options: [String], type: SelectionModelType = .none) { 20 | self.options = options 21 | self.type = type 22 | } 23 | 24 | } 25 | 26 | extension SelectionModel: ListDiffable { 27 | 28 | func diffIdentifier() -> NSObjectProtocol { 29 | return self 30 | } 31 | 32 | func isEqual(toDiffableObject object: ListDiffable?) -> Bool { 33 | return isEqual(object) 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/Models/SwipeActionSection.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import IGListKit 9 | import Foundation 10 | 11 | final class SwipeActionSection: NSObject { 12 | 13 | } 14 | 15 | extension SwipeActionSection: ListDiffable { 16 | 17 | func diffIdentifier() -> NSObjectProtocol { 18 | return self 19 | } 20 | 21 | func isEqual(toDiffableObject object: ListDiffable?) -> Bool { 22 | return self === object ? true : self.isEqual(object) 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/Models/User.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import IGListKit 9 | 10 | final class User: ListDiffable { 11 | 12 | let pk: Int 13 | let name: String 14 | let handle: String 15 | 16 | init(pk: Int, name: String, handle: String) { 17 | self.pk = pk 18 | self.name = name 19 | self.handle = handle 20 | } 21 | 22 | // MARK: ListDiffable 23 | 24 | func diffIdentifier() -> NSObjectProtocol { 25 | return pk as NSObjectProtocol 26 | } 27 | 28 | func isEqual(toDiffableObject object: ListDiffable?) -> Bool { 29 | guard self !== object else { return true } 30 | guard let object = object as? User else { return false } 31 | return name == object.name && handle == object.handle 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/Models/ViewModels/DayViewModel.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import Foundation 9 | import IGListKit 10 | 11 | final class DayViewModel { 12 | 13 | let day: Int 14 | let today: Bool 15 | let selected: Bool 16 | let appointments: Int 17 | 18 | init(day: Int, today: Bool, selected: Bool, appointments: Int) { 19 | self.day = day 20 | self.today = today 21 | self.selected = selected 22 | self.appointments = appointments 23 | } 24 | 25 | } 26 | 27 | extension DayViewModel: ListDiffable { 28 | 29 | func diffIdentifier() -> NSObjectProtocol { 30 | return day as NSObjectProtocol 31 | } 32 | 33 | func isEqual(toDiffableObject object: ListDiffable?) -> Bool { 34 | if self === object { return true } 35 | guard let object = object as? DayViewModel else { return false } 36 | return today == object.today && selected == object.selected && appointments == object.appointments 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/Models/ViewModels/MonthTitleViewModel.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import Foundation 9 | import IGListKit 10 | 11 | final class MonthTitleViewModel { 12 | 13 | let name: String 14 | 15 | init(name: String) { 16 | self.name = name 17 | } 18 | 19 | } 20 | 21 | extension MonthTitleViewModel: ListDiffable { 22 | 23 | func diffIdentifier() -> NSObjectProtocol { 24 | return name as NSObjectProtocol 25 | } 26 | 27 | func isEqual(toDiffableObject object: ListDiffable?) -> Bool { 28 | if self === object { return true } 29 | guard object is MonthTitleViewModel else { return false } 30 | // name is checked in the diffidentifier, so we can assume its equal 31 | return true 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/SectionControllers/EmbeddedSectionController.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import IGListKit 9 | import IGListSwiftKit 10 | import UIKit 11 | 12 | final class EmbeddedSectionController: ListSectionController { 13 | 14 | private var number: Int? 15 | 16 | override init() { 17 | super.init() 18 | self.inset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 10) 19 | } 20 | 21 | override func sizeForItem(at index: Int) -> CGSize { 22 | let height = collectionContext?.containerSize.height ?? 0 23 | return CGSize(width: height, height: height) 24 | } 25 | 26 | override func cellForItem(at index: Int) -> UICollectionViewCell { 27 | let cell: CenterLabelCell = collectionContext.dequeueReusableCell(for: self, at: index) 28 | let value = number ?? 0 29 | cell.text = "\(value + 1)" 30 | cell.backgroundColor = UIColor(red: 237 / 255.0, green: 73 / 255.0, blue: 86 / 255.0, alpha: 1) 31 | return cell 32 | } 33 | 34 | override func didUpdate(to object: Any) { 35 | number = object as? Int 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/SectionControllers/LabelSectionController.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import IGListKit 9 | import IGListSwiftKit 10 | import UIKit 11 | 12 | final class LabelSectionController: ListSectionController { 13 | 14 | private var object: String? 15 | 16 | override func sizeForItem(at index: Int) -> CGSize { 17 | return CGSize(width: collectionContext!.containerSize.width, height: 55) 18 | } 19 | 20 | override func cellForItem(at index: Int) -> UICollectionViewCell { 21 | let cell: LabelCell = collectionContext.dequeueReusableCell(for: self, at: index) 22 | cell.text = object 23 | return cell 24 | } 25 | 26 | override func didUpdate(to object: Any) { 27 | self.object = String(describing: object) 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/SectionControllers/PersonSectionController.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | @import IGListKit; 9 | 10 | @interface PersonSectionController : IGListSectionController 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/SectionControllers/PersonSectionController.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "PersonSectionController.h" 9 | 10 | #import "PersonCell.h" 11 | #import "PersonModel.h" 12 | 13 | @implementation PersonSectionController { 14 | PersonModel *_person; 15 | } 16 | 17 | #pragma mark - IGListSectionController Overrides 18 | 19 | - (NSInteger)numberOfItems { 20 | return 1; 21 | } 22 | 23 | - (CGSize)sizeForItemAtIndex:(NSInteger)index { 24 | const CGFloat width = self.collectionContext.containerSize.width; 25 | const CGFloat height = 74.0; 26 | return CGSizeMake(width, height); 27 | } 28 | 29 | - (UICollectionViewCell *)cellForItemAtIndex:(NSInteger)index { 30 | const Class cellClass = [PersonCell class]; 31 | PersonCell *cell = (PersonCell *)[self.collectionContext dequeueReusableCellOfClass:cellClass forSectionController:self atIndex:index]; 32 | cell.person = _person; 33 | return cell; 34 | } 35 | 36 | - (void)didUpdateToObject:(id)object { 37 | _person = (PersonModel *)object; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/SectionControllers/PostSectionController.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | @import IGListKit; 9 | 10 | @interface PostSectionController : IGListSectionController 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/SectionControllers/ReorderableSectionController.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import IGListKit 9 | import IGListSwiftKit 10 | import UIKit 11 | 12 | final class ReorderableSectionController: ListSectionController { 13 | 14 | private var object: String? 15 | 16 | override func sizeForItem(at index: Int) -> CGSize { 17 | return CGSize(width: collectionContext!.containerSize.width, height: 55) 18 | } 19 | 20 | override func cellForItem(at index: Int) -> UICollectionViewCell { 21 | let cell: LabelCell = collectionContext.dequeueReusableCell(for: self, at: index) 22 | cell.text = object 23 | return cell 24 | } 25 | 26 | override func didUpdate(to object: Any) { 27 | self.object = String(describing: object) 28 | } 29 | 30 | override func canMoveItem(at index: Int) -> Bool { 31 | return true 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/Systems/IncrementAnnouncer.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import UIKit 9 | 10 | @objc protocol IncrementListener: AnyObject { 11 | func didIncrement(announcer: IncrementAnnouncer, value: Int) 12 | } 13 | 14 | final class IncrementAnnouncer: NSObject { 15 | 16 | private var value: Int = 0 17 | private let map: NSHashTable<IncrementListener> = NSHashTable<IncrementListener>.weakObjects() 18 | 19 | func addListener(listener: IncrementListener) { 20 | map.add(listener) 21 | } 22 | 23 | func increment() { 24 | value += 1 25 | for listener in map.allObjects { 26 | listener.didIncrement(announcer: self, value: value) 27 | } 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/ViewControllers/IGListKitExamples-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "ObjcDemoViewController.h" 9 | #import "ObjcGeneratedModelDemoViewController.h" 10 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/ViewControllers/ObjcDemoViewController.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <UIKit/UIKit.h> 9 | 10 | @interface ObjcDemoViewController : UIViewController 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/ViewControllers/ObjcGeneratedModelDemoViewController.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <UIKit/UIKit.h> 9 | 10 | @interface ObjcGeneratedModelDemoViewController : UIViewController 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/Views/CenterLabelCell.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import UIKit 9 | 10 | final class CenterLabelCell: UICollectionViewCell { 11 | 12 | lazy private var label: UILabel = { 13 | let view = UILabel() 14 | view.backgroundColor = .clear 15 | view.textAlignment = .center 16 | view.textColor = .white 17 | view.font = .boldSystemFont(ofSize: 18) 18 | self.contentView.addSubview(view) 19 | return view 20 | }() 21 | 22 | var text: String? { 23 | get { 24 | return label.text 25 | } 26 | set { 27 | label.text = newValue 28 | } 29 | } 30 | 31 | override func layoutSubviews() { 32 | super.layoutSubviews() 33 | label.frame = contentView.bounds 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/Views/CommentCell.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <UIKit/UIKit.h> 9 | 10 | @interface CommentCell : UICollectionViewCell 11 | @property (nonatomic, copy) NSString *comment; 12 | @end 13 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/Views/EmbeddedCollectionViewCell.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import IGListKit 9 | import UIKit 10 | 11 | final class EmbeddedCollectionViewCell: UICollectionViewCell { 12 | 13 | lazy var collectionView: UICollectionView = { 14 | let layout = UICollectionViewFlowLayout() 15 | layout.scrollDirection = .horizontal 16 | let view = UICollectionView(frame: .zero, collectionViewLayout: layout) 17 | view.backgroundColor = .clear 18 | view.alwaysBounceVertical = false 19 | view.alwaysBounceHorizontal = true 20 | self.contentView.addSubview(view) 21 | return view 22 | }() 23 | 24 | override func layoutSubviews() { 25 | super.layoutSubviews() 26 | collectionView.frame = contentView.frame 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/Views/InteractiveCell.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <UIKit/UIKit.h> 9 | 10 | @interface InteractiveCell : UICollectionViewCell 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/Views/NibCell.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import UIKit 9 | 10 | final class NibCell: UICollectionViewCell { 11 | static let nibName = "NibCell" 12 | @IBOutlet private var textLabel: UILabel! 13 | var text: String? { 14 | didSet { 15 | textLabel.text = text 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/Views/NibSelfSizingCell.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import UIKit 9 | 10 | final class NibSelfSizingCell: UICollectionViewCell { 11 | 12 | @IBOutlet weak var contentLabel: UILabel! 13 | 14 | private var content: String? { 15 | get { 16 | return contentLabel.text 17 | } 18 | set { 19 | contentLabel.text = newValue 20 | } 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/Views/PersonCell.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <UIKit/UIKit.h> 9 | 10 | @class PersonModel; 11 | 12 | @interface PersonCell : UICollectionViewCell 13 | @property (nonatomic, copy) PersonModel *person; 14 | @end 15 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/Views/PhotoCell.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <UIKit/UIKit.h> 9 | 10 | @interface PhotoCell : UICollectionViewCell 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/Views/PhotoCell.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "PhotoCell.h" 9 | 10 | @interface PhotoCell () 11 | @property (nonatomic, strong) UIView *view; 12 | @end 13 | 14 | @implementation PhotoCell 15 | 16 | - (instancetype)init { 17 | if (self = [super init]) { 18 | [self setupSubviews]; 19 | } 20 | return self; 21 | } 22 | 23 | - (instancetype)initWithFrame:(CGRect)frame { 24 | if (self = [super initWithFrame:frame]) { 25 | [self setupSubviews]; 26 | } 27 | return self; 28 | } 29 | 30 | - (void)setupSubviews { 31 | self.view = [[UIView alloc] init]; 32 | self.view.backgroundColor = [UIColor colorWithRed:4/255.0 green:170/255.0 blue:166/255.0 alpha:1.0]; 33 | [self.contentView addSubview:self.view]; 34 | } 35 | 36 | - (void)layoutSubviews { 37 | [super layoutSubviews]; 38 | 39 | self.view.frame = self.contentView.frame; 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/Views/SearchCell.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import UIKit 9 | 10 | final class SearchCell: UICollectionViewCell { 11 | 12 | lazy var searchBar: UISearchBar = { 13 | let view = UISearchBar() 14 | self.contentView.addSubview(view) 15 | return view 16 | }() 17 | 18 | override func layoutSubviews() { 19 | super.layoutSubviews() 20 | searchBar.frame = contentView.bounds 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/Views/StoryboardCell.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import UIKit 9 | 10 | final class StoryboardCell: UICollectionViewCell { 11 | @IBOutlet private weak var textLabel: UILabel! 12 | 13 | var text: String? { 14 | get { 15 | return textLabel.text 16 | } 17 | set { 18 | textLabel.text = newValue 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/Views/UserFooterView.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import UIKit 9 | 10 | final class UserFooterView: UICollectionViewCell { 11 | 12 | @IBOutlet private weak var commentsCountLabel: UILabel! 13 | 14 | var commentsCount: String? { 15 | get { 16 | return commentsCountLabel.text 17 | } 18 | set { 19 | commentsCountLabel.text = newValue 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/Views/UserHeaderView.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import UIKit 9 | 10 | final class UserHeaderView: UICollectionViewCell { 11 | 12 | @IBOutlet private weak var nameLabel: UILabel! 13 | @IBOutlet private weak var handleLabel: UILabel! 14 | 15 | var name: String? { 16 | get { 17 | return nameLabel.text 18 | } 19 | set { 20 | nameLabel.text = newValue 21 | } 22 | } 23 | 24 | var handle: String? { 25 | get { 26 | return handleLabel.text 27 | } 28 | set { 29 | handleLabel.text = newValue 30 | } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitExamples/Views/UserInfoCell.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <UIKit/UIKit.h> 9 | 10 | @interface UserInfoCell : UICollectionViewCell 11 | @property (nonatomic, copy) NSString *name; 12 | @end 13 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitMessageExample/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitMessageExample/Info.plist: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 3 | <plist version="1.0"> 4 | <dict> 5 | <key>CFBundleDevelopmentRegion</key> 6 | <string>$(DEVELOPMENT_LANGUAGE)</string> 7 | <key>CFBundleDisplayName</key> 8 | <string>IGListKit</string> 9 | <key>CFBundleExecutable</key> 10 | <string>$(EXECUTABLE_NAME)</string> 11 | <key>CFBundleIdentifier</key> 12 | <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> 13 | <key>CFBundleInfoDictionaryVersion</key> 14 | <string>6.0</string> 15 | <key>CFBundleName</key> 16 | <string>$(PRODUCT_NAME)</string> 17 | <key>CFBundlePackageType</key> 18 | <string>XPC!</string> 19 | <key>CFBundleShortVersionString</key> 20 | <string>1.0</string> 21 | <key>CFBundleVersion</key> 22 | <string>1</string> 23 | <key>NSExtension</key> 24 | <dict> 25 | <key>NSExtensionPointIdentifier</key> 26 | <string>com.apple.message-payload-provider</string> 27 | <key>NSExtensionPrincipalClass</key> 28 | <string>IGListKitMessageExample.MessagesViewController</string> 29 | </dict> 30 | </dict> 31 | </plist> 32 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/IGListKitTodayExample/Info.plist: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 3 | <plist version="1.0"> 4 | <dict> 5 | <key>CFBundleDevelopmentRegion</key> 6 | <string>$(DEVELOPMENT_LANGUAGE)</string> 7 | <key>CFBundleDisplayName</key> 8 | <string>IGListKit</string> 9 | <key>CFBundleExecutable</key> 10 | <string>$(EXECUTABLE_NAME)</string> 11 | <key>CFBundleIdentifier</key> 12 | <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> 13 | <key>CFBundleInfoDictionaryVersion</key> 14 | <string>6.0</string> 15 | <key>CFBundleName</key> 16 | <string>$(PRODUCT_NAME)</string> 17 | <key>CFBundlePackageType</key> 18 | <string>XPC!</string> 19 | <key>CFBundleShortVersionString</key> 20 | <string>1.0</string> 21 | <key>CFBundleVersion</key> 22 | <string>1</string> 23 | <key>NSExtension</key> 24 | <dict> 25 | <key>NSExtensionPointIdentifier</key> 26 | <string>com.apple.widget-extension</string> 27 | <key>NSExtensionPrincipalClass</key> 28 | <string>IGListKitTodayExample.TodayViewController</string> 29 | </dict> 30 | </dict> 31 | </plist> 32 | -------------------------------------------------------------------------------- /Examples/Examples-iOS/LICENSE-examples.md: -------------------------------------------------------------------------------- 1 | Copyright (c) Meta Platforms, Inc. and affiliates. 2 | 3 | The examples provided by Facebook are for non-commercial testing and evaluation 4 | purposes only. Facebook reserves all rights not expressly granted. 5 | 6 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 7 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 8 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 9 | FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 10 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 11 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 12 | -------------------------------------------------------------------------------- /Examples/Examples-macOS/IGListKitExamples.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <Workspace 3 | version = "1.0"> 4 | <FileRef 5 | location = "self:IGListKitExamples.xcodeproj"> 6 | </FileRef> 7 | </Workspace> 8 | -------------------------------------------------------------------------------- /Examples/Examples-macOS/IGListKitExamples/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import Cocoa 9 | 10 | @NSApplicationMain 11 | final class AppDelegate: NSObject, NSApplicationDelegate { 12 | 13 | func applicationDidFinishLaunching(_ aNotification: Notification) { 14 | } 15 | 16 | func applicationWillTerminate(_ aNotification: Notification) { 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Examples/Examples-macOS/IGListKitExamples/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /Examples/Examples-macOS/IGListKitExamples/Helpers/IndexSet+Extensions.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import Foundation 9 | 10 | extension IndexSet { 11 | 12 | static var zero: IndexSet { 13 | return NSIndexSet(index: 0) as IndexSet 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /Examples/Examples-macOS/IGListKitExamples/Helpers/Shuffle.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import Foundation 9 | 10 | extension MutableCollection { 11 | 12 | /// Shuffles the contents of this collection. 13 | mutating func shuffle() { 14 | guard count > 1 else { return } 15 | 16 | for (firstUnshuffled, unshuffledCount) in zip(indices, stride(from: count, to: 1, by: -1)) { 17 | let distance: Int = numericCast(arc4random_uniform(numericCast(unshuffledCount))) 18 | guard distance != 0 else { continue } 19 | 20 | let shuffleIndex = index(firstUnshuffled, offsetBy: distance) 21 | 22 | self.swapAt(firstUnshuffled, shuffleIndex) 23 | } 24 | } 25 | 26 | } 27 | 28 | extension Sequence { 29 | 30 | /// Returns an array with the contents of this sequence, shuffled. 31 | var shuffled: [Iterator.Element] { 32 | var result = Array(self) 33 | result.shuffle() 34 | 35 | return result 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /Examples/Examples-macOS/IGListKitExamples/Helpers/UsersProvider.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import Foundation 9 | 10 | final class UsersProvider { 11 | 12 | enum UsersError: Error { 13 | case invalidData 14 | } 15 | 16 | let users: [User] 17 | 18 | init(with file: URL) throws { 19 | let data = try Data(contentsOf: file) 20 | let json = try JSONSerialization.jsonObject(with: data, options: []) 21 | 22 | guard let dicts = json as? [[String: String]] else { 23 | throw UsersError.invalidData 24 | } 25 | 26 | self.users = dicts.enumerated().compactMap { index, dict in 27 | guard let name = dict["name"] else { return nil } 28 | 29 | return User(pk: index, name: name.capitalized) 30 | }.sorted(by: { $0.name < $1.name }) 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /Examples/Examples-macOS/IGListKitExamples/Info.plist: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 3 | <plist version="1.0"> 4 | <dict> 5 | <key>CFBundleDevelopmentRegion</key> 6 | <string>en</string> 7 | <key>CFBundleExecutable</key> 8 | <string>$(EXECUTABLE_NAME)</string> 9 | <key>CFBundleIconFile</key> 10 | <string></string> 11 | <key>CFBundleIdentifier</key> 12 | <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> 13 | <key>CFBundleInfoDictionaryVersion</key> 14 | <string>6.0</string> 15 | <key>CFBundleName</key> 16 | <string>$(PRODUCT_NAME)</string> 17 | <key>CFBundlePackageType</key> 18 | <string>APPL</string> 19 | <key>CFBundleShortVersionString</key> 20 | <string>1.0</string> 21 | <key>CFBundleVersion</key> 22 | <string>1</string> 23 | <key>LSMinimumSystemVersion</key> 24 | <string>$(MACOSX_DEPLOYMENT_TARGET)</string> 25 | <key>NSHumanReadableCopyright</key> 26 | <string>Copyright (c) Meta Platforms, Inc. and affiliates.</string> 27 | <key>NSMainStoryboardFile</key> 28 | <string>Main</string> 29 | <key>NSPrincipalClass</key> 30 | <string>NSApplication</string> 31 | </dict> 32 | </plist> 33 | -------------------------------------------------------------------------------- /Examples/Examples-macOS/IGListKitExamples/Models/User.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import Foundation 9 | import IGListDiffKit 10 | 11 | final class User: ListDiffable { 12 | 13 | let pk: Int 14 | let name: String 15 | 16 | init(pk: Int, name: String) { 17 | self.pk = pk 18 | self.name = name 19 | } 20 | 21 | // MARK: ListDiffable 22 | 23 | func diffIdentifier() -> NSObjectProtocol { 24 | return pk as NSObjectProtocol 25 | } 26 | 27 | func isEqual(toDiffableObject object: ListDiffable?) -> Bool { 28 | guard self !== object else { return true } 29 | guard let object = object as? User else { return false } 30 | return name == object.name 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /Examples/Examples-macOS/IGListKitExamples/View/UserCollectionViewCell.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import Cocoa 9 | 10 | protocol UserCollectionViewCellDelegate: AnyObject { 11 | 12 | func itemDeleted(_ user: User) 13 | } 14 | 15 | final class UserCollectionViewCell: NSCollectionViewItem { 16 | 17 | weak var delegate: UserCollectionViewCellDelegate? 18 | 19 | @IBAction func deleteButtonClicked(_ sender: AnyObject) { 20 | guard let user = representedObject as? User else { return } 21 | delegate?.itemDeleted(user) 22 | } 23 | 24 | func bindViewModel(_ user: User) { 25 | representedObject = user 26 | textField?.stringValue = user.name 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Examples/Examples-macOS/LICENSE-examples.md: -------------------------------------------------------------------------------- 1 | Copyright (c) Meta Platforms, Inc. and affiliates. 2 | 3 | The examples provided by Facebook are for non-commercial testing and evaluation 4 | purposes only. Facebook reserves all rights not expressly granted. 5 | 6 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 7 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 8 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 9 | FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 10 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 11 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 12 | -------------------------------------------------------------------------------- /Examples/Examples-tvOS/IGListKitExamples.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <Workspace 3 | version = "1.0"> 4 | <FileRef 5 | location = "self:IGListKitExamples.xcodeproj"> 6 | </FileRef> 7 | </Workspace> 8 | -------------------------------------------------------------------------------- /Examples/Examples-tvOS/IGListKitExamples/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import UIKit 9 | 10 | @main 11 | class AppDelegate: UIResponder, UIApplicationDelegate { 12 | 13 | var window: UIWindow? 14 | 15 | func application(_ application: UIApplication, 16 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 17 | 18 | window = UIWindow(frame: UIScreen.main.bounds) 19 | window?.rootViewController = UINavigationController(rootViewController: DemosViewController()) 20 | window?.makeKeyAndVisible() 21 | return true 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /Examples/Examples-tvOS/IGListKitExamples/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Examples/Examples-tvOS/IGListKitExamples/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Examples/Examples-tvOS/IGListKitExamples/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers" : [ 3 | { 4 | "filename" : "Front.imagestacklayer" 5 | }, 6 | { 7 | "filename" : "Middle.imagestacklayer" 8 | }, 9 | { 10 | "filename" : "Back.imagestacklayer" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Examples/Examples-tvOS/IGListKitExamples/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Front.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Examples/Examples-tvOS/IGListKitExamples/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Front.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Examples/Examples-tvOS/IGListKitExamples/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Examples/Examples-tvOS/IGListKitExamples/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Middle.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Examples/Examples-tvOS/IGListKitExamples/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Examples/Examples-tvOS/IGListKitExamples/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Examples/Examples-tvOS/IGListKitExamples/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers" : [ 3 | { 4 | "filename" : "Front.imagestacklayer" 5 | }, 6 | { 7 | "filename" : "Middle.imagestacklayer" 8 | }, 9 | { 10 | "filename" : "Back.imagestacklayer" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Examples/Examples-tvOS/IGListKitExamples/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Front.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Examples/Examples-tvOS/IGListKitExamples/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Front.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Examples/Examples-tvOS/IGListKitExamples/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Examples/Examples-tvOS/IGListKitExamples/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Middle.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Examples/Examples-tvOS/IGListKitExamples/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "assets" : [ 3 | { 4 | "size" : "1280x768", 5 | "idiom" : "tv", 6 | "filename" : "App Icon - Large.imagestack", 7 | "role" : "primary-app-icon" 8 | }, 9 | { 10 | "size" : "400x240", 11 | "idiom" : "tv", 12 | "filename" : "App Icon - Small.imagestack", 13 | "role" : "primary-app-icon" 14 | }, 15 | { 16 | "size" : "2320x720", 17 | "idiom" : "tv", 18 | "filename" : "Top Shelf Image Wide.imageset", 19 | "role" : "top-shelf-image-wide" 20 | }, 21 | { 22 | "size" : "1920x720", 23 | "idiom" : "tv", 24 | "filename" : "Top Shelf Image.imageset", 25 | "role" : "top-shelf-image" 26 | } 27 | ], 28 | "info" : { 29 | "version" : 1, 30 | "author" : "xcode" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Examples/Examples-tvOS/IGListKitExamples/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Examples/Examples-tvOS/IGListKitExamples/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Examples/Examples-tvOS/IGListKitExamples/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Examples/Examples-tvOS/IGListKitExamples/Assets.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "landscape", 5 | "idiom" : "tv", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "9.0", 8 | "scale" : "1x" 9 | } 10 | ], 11 | "info" : { 12 | "version" : 1, 13 | "author" : "xcode" 14 | } 15 | } -------------------------------------------------------------------------------- /Examples/Examples-tvOS/IGListKitExamples/Info.plist: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 3 | <plist version="1.0"> 4 | <dict> 5 | <key>CFBundleDevelopmentRegion</key> 6 | <string>en</string> 7 | <key>CFBundleDisplayName</key> 8 | <string>IGListKit</string> 9 | <key>CFBundleExecutable</key> 10 | <string>$(EXECUTABLE_NAME)</string> 11 | <key>CFBundleIdentifier</key> 12 | <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> 13 | <key>CFBundleInfoDictionaryVersion</key> 14 | <string>6.0</string> 15 | <key>CFBundleName</key> 16 | <string>$(PRODUCT_NAME)</string> 17 | <key>CFBundlePackageType</key> 18 | <string>APPL</string> 19 | <key>CFBundleShortVersionString</key> 20 | <string>1.0</string> 21 | <key>CFBundleVersion</key> 22 | <string>1</string> 23 | <key>LSRequiresIPhoneOS</key> 24 | <true/> 25 | <key>UIRequiredDeviceCapabilities</key> 26 | <array> 27 | <string>arm64</string> 28 | </array> 29 | <key>UIUserInterfaceStyle</key> 30 | <string>Automatic</string> 31 | </dict> 32 | </plist> 33 | -------------------------------------------------------------------------------- /Examples/Examples-tvOS/IGListKitExamples/Models/NSObject+IGListDiffable.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import Foundation 9 | import IGListKit 10 | 11 | extension NSObject: ListDiffable { 12 | 13 | public func diffIdentifier() -> NSObjectProtocol { 14 | return self 15 | } 16 | 17 | public func isEqual(toDiffableObject object: ListDiffable?) -> Bool { 18 | return isEqual(object) 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /Examples/Examples-tvOS/IGListKitExamples/SectionControllers/LabelSectionController.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import IGListKit 9 | import IGListSwiftKit 10 | import UIKit 11 | 12 | final class LabelSectionController: ListSectionController { 13 | 14 | var object: String? 15 | 16 | override func numberOfItems() -> Int { 17 | return 1 18 | } 19 | 20 | override func sizeForItem(at index: Int) -> CGSize { 21 | return CGSize(width: collectionContext!.containerSize.width, height: 55) 22 | } 23 | 24 | override func cellForItem(at index: Int) -> UICollectionViewCell { 25 | guard let cell: LabelCell = collectionContext?.dequeueReusableCell(for: self, at: index) else { 26 | fatalError() 27 | } 28 | cell.label.text = object 29 | return cell 30 | } 31 | 32 | override func didUpdate(to object: Any) { 33 | self.object = String(describing: object) 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /Examples/Examples-tvOS/IGListKitExamples/Views/CarouselCell.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import UIKit 9 | 10 | final class CarouselCell: UICollectionViewCell { 11 | @IBOutlet weak var titleLabel: UILabel! 12 | 13 | override func didUpdateFocus(in context: UIFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) { 14 | let normalColor = UIColor(red: 174 / 255.0, green: 198 / 255.0, blue: 207 / 255.0, alpha: 1) 15 | let focusColor = UIColor(red: 117 / 255.0, green: 155 / 255.0, blue: 169 / 255.0, alpha: 1) 16 | 17 | backgroundColor = isFocused ? focusColor : normalColor 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Examples/Examples-tvOS/IGListKitExamples/Views/DemoCell.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import UIKit 9 | 10 | final class DemoCell: UICollectionViewCell { 11 | 12 | lazy var label: UILabel = { 13 | let view = UILabel() 14 | view.textColor = .black 15 | view.font = .boldSystemFont(ofSize: 35) 16 | self.contentView.addSubview(view) 17 | return view 18 | }() 19 | 20 | override func layoutSubviews() { 21 | super.layoutSubviews() 22 | contentView.backgroundColor = UIColor.white.withAlphaComponent(0.3) 23 | label.frame = contentView.bounds.insetBy(dx: 32, dy: 16) 24 | } 25 | 26 | override func didUpdateFocus(in context: UIFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) { 27 | let newBackgroundOpacity: CGFloat = isFocused ? 0.6 : 0.3 28 | let newFontSize: CGFloat = isFocused ? 50 : 35 29 | 30 | contentView.backgroundColor = UIColor.white.withAlphaComponent(newBackgroundOpacity) 31 | label.font = .boldSystemFont(ofSize: newFontSize) 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /Examples/Examples-tvOS/IGListKitExamples/Views/EmbeddedCollectionViewCell.swift: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import IGListKit 9 | import UIKit 10 | 11 | final class EmbeddedCollectionViewCell: UICollectionViewCell { 12 | 13 | lazy var collectionView: UICollectionView = { 14 | let layout = UICollectionViewFlowLayout() 15 | layout.scrollDirection = .horizontal 16 | let view = UICollectionView(frame: .zero, collectionViewLayout: layout) 17 | view.backgroundColor = .clear 18 | view.alwaysBounceVertical = false 19 | view.alwaysBounceHorizontal = true 20 | self.contentView.addSubview(view) 21 | return view 22 | }() 23 | 24 | override func layoutSubviews() { 25 | super.layoutSubviews() 26 | collectionView.frame = contentView.frame 27 | } 28 | 29 | override var canBecomeFocused: Bool { 30 | return false 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /Examples/Examples-tvOS/LICENSE-examples.md: -------------------------------------------------------------------------------- 1 | Copyright (c) Meta Platforms, Inc. and affiliates. 2 | 3 | The examples provided by Facebook are for non-commercial testing and evaluation 4 | purposes only. Facebook reserves all rights not expressly granted. 5 | 6 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 7 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 8 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 9 | FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 10 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 11 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 12 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'cocoapods', '~> 1.14.2' 4 | gem 'danger', '~> 9.3.1' 5 | gem 'danger-swiftlint', '~> 0.33.0' 6 | gem 'slather', '~> 2.7.4' 7 | gem 'xcpretty', '~> 0.3.0' 8 | -------------------------------------------------------------------------------- /IGListKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <Workspace 3 | version = "1.0"> 4 | <FileRef 5 | location = "self:IGListKit.xcodeproj"> 6 | </FileRef> 7 | </Workspace> 8 | -------------------------------------------------------------------------------- /IGListKit.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 3 | <plist version="1.0"> 4 | <dict> 5 | <key>IDEDidComputeMac32BitWarning</key> 6 | <true/> 7 | </dict> 8 | </plist> 9 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Meta Platforms, Inc. and affiliates. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.0 2 | import PackageDescription 3 | 4 | let package = Package( 5 | name: "IGListKit", 6 | platforms: [ .iOS(.v11), 7 | .tvOS(.v11), 8 | .macOS(.v10_13), 9 | ], 10 | products: [ 11 | .library(name: "IGListDiffKit", 12 | targets: ["IGListDiffKit"]), 13 | .library(name: "IGListKit", 14 | targets: ["IGListKit"]), 15 | .library(name: "IGListSwiftKit", 16 | targets: ["IGListSwiftKit"]), 17 | ], 18 | targets: [ 19 | .target( 20 | name: "IGListDiffKit", 21 | path: "spm/Sources/IGListDiffKit", 22 | publicHeadersPath: "include" 23 | ), 24 | .target( 25 | name: "IGListKit", 26 | dependencies: ["IGListDiffKit"], 27 | path: "spm/Sources/IGListKit", 28 | publicHeadersPath: "include" 29 | ), 30 | .target( 31 | name: "IGListSwiftKit", 32 | dependencies: ["IGListKit"], 33 | path: "spm/Sources/IGListSwiftKit" 34 | ), 35 | ], 36 | cLanguageStandard: .c11, 37 | cxxLanguageStandard: .cxx11 38 | ) 39 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | source 'https://cdn.cocoapods.org' 2 | use_frameworks! 3 | inhibit_all_warnings! 4 | 5 | workspace 'IGListKit' 6 | 7 | target 'IGListKitTests' do 8 | platform :ios, '11.0' 9 | pod 'OCMock', '~> 3.8.1' 10 | end 11 | 12 | target 'IGListKit-tvOSTests' do 13 | platform :tvos, '11.0' 14 | pod 'OCMock', '~> 3.8.1' 15 | end 16 | -------------------------------------------------------------------------------- /Resources/binding-flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Instagram/IGListKit/01bd505d8b89b55fc3938fc5ce4a9f57a7a92f81/Resources/binding-flow.png -------------------------------------------------------------------------------- /Resources/logo-animation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Instagram/IGListKit/01bd505d8b89b55fc3938fc5ce4a9f57a7a92f81/Resources/logo-animation.gif -------------------------------------------------------------------------------- /Resources/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Instagram/IGListKit/01bd505d8b89b55fc3938fc5ce4a9f57a7a92f81/Resources/logo.png -------------------------------------------------------------------------------- /Resources/modeling-design.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Instagram/IGListKit/01bd505d8b89b55fc3938fc5ce4a9f57a7a92f81/Resources/modeling-design.png -------------------------------------------------------------------------------- /Resources/modeling-likes.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Instagram/IGListKit/01bd505d8b89b55fc3938fc5ce4a9f57a7a92f81/Resources/modeling-likes.gif -------------------------------------------------------------------------------- /Resources/modeling-working.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Instagram/IGListKit/01bd505d8b89b55fc3938fc5ce4a9f57a7a92f81/Resources/modeling-working.png -------------------------------------------------------------------------------- /Resources/replace-iglistcollectionview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Instagram/IGListKit/01bd505d8b89b55fc3938fc5ce4a9f57a7a92f81/Resources/replace-iglistcollectionview.png -------------------------------------------------------------------------------- /Resources/workingrange.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Instagram/IGListKit/01bd505d8b89b55fc3938fc5ce4a9f57a7a92f81/Resources/workingrange.png -------------------------------------------------------------------------------- /Source/IGListDiffKit/IGListCompatibility.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <TargetConditionals.h> 9 | 10 | #if TARGET_OS_EMBEDDED || TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST 11 | #import <UIKit/UIKit.h> 12 | #else 13 | #import <Cocoa/Cocoa.h> 14 | #endif 15 | -------------------------------------------------------------------------------- /Source/IGListDiffKit/IGListDiffKit.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "IGListCompatibility.h" 9 | 10 | /** 11 | * Project version number for IGListKit. 12 | */ 13 | FOUNDATION_EXPORT double IGListKitVersionNumber; 14 | 15 | /** 16 | * Project version string for IGListKit. 17 | */ 18 | FOUNDATION_EXPORT const unsigned char IGListKitVersionString[]; 19 | 20 | #import "IGListAssert.h" 21 | #import "IGListBatchUpdateData.h" 22 | #import "IGListDiff.h" 23 | #import "IGListDiffable.h" 24 | #import "IGListExperiments.h" 25 | #import "IGListIndexPathResult.h" 26 | #import "IGListIndexSetResult.h" 27 | #import "IGListMoveIndex.h" 28 | #import "IGListMoveIndexPath.h" 29 | #import "NSNumber+IGListDiffable.h" 30 | #import "NSString+IGListDiffable.h" 31 | -------------------------------------------------------------------------------- /Source/IGListDiffKit/IGListDiffable.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | /** 11 | The `IGListDiffable` protocol provides methods needed to compare the identity and equality of two objects. 12 | */ 13 | NS_SWIFT_NAME(ListDiffable) 14 | @protocol IGListDiffable 15 | 16 | /** 17 | Returns a key that uniquely identifies the object. 18 | 19 | @return A key that can be used to uniquely identify the object. 20 | 21 | @note Two objects may share the same identifier, but are not equal. A common pattern is to use the `NSObject` 22 | category for automatic conformance. However this means that objects will be identified on their 23 | pointer value so finding updates becomes impossible. 24 | 25 | @warning This value should never be mutated. 26 | */ 27 | - (nonnull id<NSObject>)diffIdentifier; 28 | 29 | /** 30 | Returns whether the receiver and a given object are equal. 31 | 32 | @param object The object to be compared to the receiver. 33 | 34 | @return `YES` if the receiver and object are equal, otherwise `NO`. 35 | */ 36 | - (BOOL)isEqualToDiffableObject:(nullable id<IGListDiffable>)object; 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /Source/IGListDiffKit/IGListMoveIndex.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | /** 13 | An object representing a move between indexes. 14 | */ 15 | NS_SWIFT_NAME(ListMoveIndex) 16 | @interface IGListMoveIndex : NSObject 17 | 18 | /** 19 | An index in the old collection. 20 | */ 21 | @property (nonatomic, assign, readonly) NSInteger from; 22 | 23 | /** 24 | An index in the new collection. 25 | */ 26 | @property (nonatomic, assign, readonly) NSInteger to; 27 | 28 | /** 29 | :nodoc: 30 | */ 31 | - (instancetype)init NS_UNAVAILABLE; 32 | 33 | /** 34 | :nodoc: 35 | */ 36 | + (instancetype)new NS_UNAVAILABLE; 37 | 38 | @end 39 | 40 | NS_ASSUME_NONNULL_END 41 | -------------------------------------------------------------------------------- /Source/IGListDiffKit/IGListMoveIndexPath.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | /** 13 | An object representing a move between indexes. 14 | */ 15 | NS_SWIFT_NAME(ListMoveIndexPath) 16 | @interface IGListMoveIndexPath : NSObject 17 | 18 | /** 19 | An index path in the old collection. 20 | */ 21 | @property (nonatomic, strong, readonly) NSIndexPath *from; 22 | 23 | /** 24 | An index path in the new collection. 25 | */ 26 | @property (nonatomic, strong, readonly) NSIndexPath *to; 27 | 28 | /** 29 | :nodoc: 30 | */ 31 | - (instancetype)init NS_UNAVAILABLE; 32 | 33 | /** 34 | :nodoc: 35 | */ 36 | + (instancetype)new NS_UNAVAILABLE; 37 | 38 | @end 39 | 40 | NS_ASSUME_NONNULL_END 41 | -------------------------------------------------------------------------------- /Source/IGListDiffKit/Internal/IGListIndexPathResultInternal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | #import "IGListIndexPathResult.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface IGListIndexPathResult() 15 | 16 | - (instancetype)initWithInserts:(NSArray<NSIndexPath *> *)inserts 17 | deletes:(NSArray<NSIndexPath *> *)deletes 18 | updates:(NSArray<NSIndexPath *> *)updates 19 | moves:(NSArray<IGListMoveIndexPath *> *)moves 20 | oldIndexPathMap:(NSMapTable<id<NSObject>, NSIndexPath *> *)oldIndexPathMap 21 | newIndexPathMap:(NSMapTable<id<NSObject>, NSIndexPath *> *)newIndexPathMap; 22 | 23 | @property (nonatomic, assign, readonly) NSInteger changeCount; 24 | 25 | @end 26 | 27 | NS_ASSUME_NONNULL_END 28 | -------------------------------------------------------------------------------- /Source/IGListDiffKit/Internal/IGListIndexSetResultInternal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | #if !__has_include(<IGListDiffKit/IGListDiffKit.h>) 11 | #import "IGListIndexSetResult.h" 12 | #else 13 | #import <IGListDiffKit/IGListIndexSetResult.h> 14 | #endif 15 | 16 | NS_ASSUME_NONNULL_BEGIN 17 | 18 | @interface IGListIndexSetResult() 19 | 20 | - (instancetype)initWithInserts:(NSIndexSet *)inserts 21 | deletes:(NSIndexSet *)deletes 22 | updates:(NSIndexSet *)updates 23 | moves:(NSArray<IGListMoveIndex *> *)moves 24 | oldIndexMap:(NSMapTable<id<NSObject>, NSNumber *> *)oldIndexMap 25 | newIndexMap:(NSMapTable<id<NSObject>, NSNumber *> *)newIndexMap; 26 | 27 | @property (nonatomic, assign, readonly) NSInteger changeCount; 28 | 29 | @end 30 | 31 | NS_ASSUME_NONNULL_END 32 | -------------------------------------------------------------------------------- /Source/IGListDiffKit/Internal/IGListMoveIndexInternal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | #import "IGListMoveIndex.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface IGListMoveIndex () 15 | 16 | - (instancetype)initWithFrom:(NSInteger)from to:(NSInteger)to NS_DESIGNATED_INITIALIZER; 17 | 18 | @end 19 | 20 | NS_ASSUME_NONNULL_END 21 | -------------------------------------------------------------------------------- /Source/IGListDiffKit/Internal/IGListMoveIndexPathInternal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | @interface IGListMoveIndexPath () 13 | 14 | - (instancetype)initWithFrom:(NSIndexPath *)from to:(NSIndexPath *)to NS_DESIGNATED_INITIALIZER; 15 | 16 | @end 17 | 18 | NS_ASSUME_NONNULL_END 19 | -------------------------------------------------------------------------------- /Source/IGListDiffKit/NSNumber+IGListDiffable.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | #import "IGListDiffable.h" 11 | /** 12 | This category provides default `IGListDiffable` conformance for `NSNumber`. 13 | */ 14 | @interface NSNumber (IGListDiffable) <IGListDiffable> 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Source/IGListDiffKit/NSNumber+IGListDiffable.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "NSNumber+IGListDiffable.h" 9 | 10 | @implementation NSNumber (IGListDiffable) 11 | 12 | - (id<NSObject>)diffIdentifier { 13 | return self; 14 | } 15 | 16 | - (BOOL)isEqualToDiffableObject:(id<IGListDiffable>)object { 17 | return [self isEqual:object]; 18 | } 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /Source/IGListDiffKit/NSString+IGListDiffable.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | #import "IGListDiffable.h" 11 | 12 | /** 13 | This category provides default `IGListDiffable` conformance for `NSString`. 14 | */ 15 | @interface NSString (IGListDiffable) <IGListDiffable> 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Source/IGListDiffKit/NSString+IGListDiffable.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "NSString+IGListDiffable.h" 9 | 10 | @implementation NSString (IGListDiffable) 11 | 12 | - (id<NSObject>)diffIdentifier { 13 | return self; 14 | } 15 | 16 | - (BOOL)isEqualToDiffableObject:(id<IGListDiffable>)object { 17 | return [self isEqual:object]; 18 | } 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /Source/IGListKit/IGListAdapterDelegateAnnouncer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | #import "IGListAdapterDelegate.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface IGListAdapterDelegateAnnouncer : NSObject 15 | 16 | /// Default announcer for all `IGListAdapter` 17 | + (instancetype)sharedInstance; 18 | 19 | /// Add a delegate that will receive callbacks for all `IGListAdapter`. 20 | /// This is a weak reference, so you don't need to remove it on dealloc. 21 | - (void)addListener:(id<IGListAdapterDelegate>)listener; 22 | 23 | /// Remove delegate 24 | - (void)removeListener:(id<IGListAdapterDelegate>)listener; 25 | 26 | @end 27 | 28 | NS_ASSUME_NONNULL_END 29 | -------------------------------------------------------------------------------- /Source/IGListKit/IGListAdapterMoveDelegate.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | @class IGListAdapter; 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | /** 15 | Conform to `IGListAdapterMoveDelegate` to receive interactive reordering requests. 16 | */ 17 | NS_SWIFT_UI_ACTOR 18 | NS_SWIFT_NAME(ListAdapterMoveDelegate) 19 | @protocol IGListAdapterMoveDelegate <NSObject> 20 | 21 | /** 22 | Asks the delegate to move a section object as the result of interactive reordering. 23 | 24 | @param listAdapter The list adapter sending this information. 25 | @param object the object that was moved 26 | @param previousObjects The array of objects prior to the move. 27 | @param objects The array of objects after the move. 28 | */ 29 | - (void)listAdapter:(IGListAdapter *)listAdapter 30 | moveObject:(id)object 31 | from:(NSArray *)previousObjects 32 | to:(NSArray *)objects; 33 | 34 | @end 35 | 36 | NS_ASSUME_NONNULL_END 37 | -------------------------------------------------------------------------------- /Source/IGListKit/IGListBindable.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | /** 13 | A protocol for cells that configure themselves given a view model. 14 | */ 15 | NS_SWIFT_UI_ACTOR 16 | NS_SWIFT_NAME(ListBindable) 17 | @protocol IGListBindable <NSObject> 18 | 19 | /** 20 | Tells the cell to configure itself with the given view model. 21 | 22 | @param viewModel The view model for the cell. 23 | 24 | @note The view model can change many times throughout the lifetime of a cell as the model values change and the cell 25 | is reused. Implementations should use only this method to do their configuration. 26 | */ 27 | - (void)bindViewModel:(id)viewModel; 28 | 29 | @end 30 | 31 | NS_ASSUME_NONNULL_END 32 | -------------------------------------------------------------------------------- /Source/IGListKit/IGListCollectionScrollingTraits.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | /** 11 | The current scrolling traits of the underlying collection view. 12 | The attributes are always equal to their corresponding properties on the underlying collection view. 13 | */ 14 | NS_SWIFT_NAME(ListCollectionScrollingTraits) 15 | typedef struct IGListCollectionScrollingTraits { 16 | /// returns YES if user has touched. may not yet have started dragging. 17 | bool isTracking; 18 | /// returns YES if user has started scrolling. this may require some time and or distance to move to initiate dragging 19 | bool isDragging; 20 | /// returns YES if user isn't dragging (touch up) but scroll view is still moving. 21 | bool isDecelerating; 22 | } IGListCollectionScrollingTraits; 23 | -------------------------------------------------------------------------------- /Source/IGListKit/IGListCollectionViewLayoutInvalidationContext.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <UIKit/UIKit.h> 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | /** 13 | The default invalidation context class used by IGListCollectionViewLayout. 14 | */ 15 | NS_SWIFT_NAME(ListCollectionViewLayoutInvalidationContext) 16 | @interface IGListCollectionViewLayoutInvalidationContext : UICollectionViewLayoutInvalidationContext 17 | 18 | /** 19 | False by default. If true, supplementary list item attributes (headers and footers) will be invalidated. 20 | */ 21 | @property (nonatomic, assign) BOOL invalidateSupplementaryListAttributes; 22 | 23 | /** 24 | False by default. If true, all list item attributes will be invalidated. 25 | */ 26 | @property (nonatomic, assign) BOOL invalidateAllListAttributes; 27 | 28 | @end 29 | 30 | NS_ASSUME_NONNULL_END 31 | -------------------------------------------------------------------------------- /Source/IGListKit/IGListCollectionViewLayoutInvalidationContext.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "IGListCollectionViewLayoutInvalidationContext.h" 9 | 10 | @implementation IGListCollectionViewLayoutInvalidationContext 11 | @end 12 | -------------------------------------------------------------------------------- /Source/IGListKit/IGListGenericSectionController.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "IGListGenericSectionController.h" 9 | 10 | @implementation IGListGenericSectionController 11 | 12 | - (void)didUpdateToObject:(id)object { 13 | _object = object; 14 | } 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Source/IGListKit/IGListReloadDataUpdater.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <UIKit/UIKit.h> 9 | 10 | #if !__has_include(<IGListDiffKit/IGListDiffKit.h>) 11 | #import "IGListMacros.h" 12 | #else 13 | #import <IGListDiffKit/IGListMacros.h> 14 | #endif 15 | 16 | #import "IGListUpdatingDelegate.h" 17 | 18 | NS_ASSUME_NONNULL_BEGIN 19 | 20 | /** 21 | An `IGListReloadDataUpdater` is a concrete type that conforms to `IGListUpdatingDelegate`. 22 | It is an out-of-box updater for `IGListAdapter` objects to use. 23 | 24 | @note This updater performs simple, synchronous updates using `-[UICollectionView reloadData]`. 25 | */ 26 | IGLK_SUBCLASSING_RESTRICTED 27 | NS_SWIFT_NAME(ListReloadDataUpdater) 28 | @interface IGListReloadDataUpdater : NSObject <IGListUpdatingDelegate> 29 | 30 | @end 31 | 32 | NS_ASSUME_NONNULL_END 33 | -------------------------------------------------------------------------------- /Source/IGListKit/IGListTransitionData.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "IGListTransitionData.h" 9 | 10 | @implementation IGListTransitionData 11 | 12 | - (instancetype)initFromObjects:(NSArray *)fromObjects 13 | toObjects:(NSArray *)toObjects 14 | toSectionControllers:(NSArray<IGListSectionController *> *)toSectionControllers { 15 | if (self = [super init]) { 16 | _fromObjects = [fromObjects copy]; 17 | _toObjects = [toObjects copy]; 18 | _toSectionControllers = [toSectionControllers copy]; 19 | } 20 | return self; 21 | } 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Source/IGListKit/Internal/IGListAdapter+DebugDescription.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "IGListAdapter.h" 9 | 10 | @interface IGListAdapter (DebugDescription) 11 | 12 | - (NSArray<NSString *> *)debugDescriptionLines; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Source/IGListKit/Internal/IGListAdapter+UICollectionView.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <UIKit/UIKit.h> 9 | 10 | #import "IGListAdapter.h" 11 | #import "IGListCollectionViewDelegateLayout.h" 12 | 13 | @interface IGListAdapter (UICollectionView) 14 | < 15 | UICollectionViewDataSource, 16 | IGListCollectionViewDelegateLayout 17 | > 18 | @end 19 | -------------------------------------------------------------------------------- /Source/IGListKit/Internal/IGListAdapterDelegateAnnouncerInternal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "IGListAdapterDelegateAnnouncer.h" 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | @interface IGListAdapterDelegateAnnouncer () 13 | 14 | - (void)announceObjectDisplayWithAdapter:(IGListAdapter *)listAdapter object:(id)object index:(NSInteger)index; 15 | - (void)announceObjectEndDisplayWithAdapter:(IGListAdapter *)listAdapter object:(id)object index:(NSInteger)index; 16 | 17 | - (void)announceCellDisplayWithAdapter:(IGListAdapter *)listAdapter object:(id)object cell:(UICollectionViewCell *)cell indexPath:(NSIndexPath *)indexPath; 18 | - (void)announceCellEndDisplayWithAdapter:(IGListAdapter *)listAdapter object:(id)object cell:(UICollectionViewCell *)cell indexPath:(NSIndexPath *)indexPath; 19 | 20 | @end 21 | 22 | NS_ASSUME_NONNULL_END 23 | -------------------------------------------------------------------------------- /Source/IGListKit/Internal/IGListAdapterUpdater+DebugDescription.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "IGListAdapterUpdater.h" 9 | 10 | @interface IGListAdapterUpdater (DebugDescription) 11 | 12 | - (NSArray<NSString *> *)debugDescriptionLines; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Source/IGListKit/Internal/IGListAdapterUpdaterInternal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | #import "IGListAdapterUpdater.h" 11 | #import "IGListBatchUpdateState.h" 12 | 13 | @class IGListUpdateTransactionBuilder; 14 | @protocol IGListUpdateTransactable; 15 | 16 | NS_ASSUME_NONNULL_BEGIN 17 | 18 | @interface IGListAdapterUpdater () 19 | 20 | - (BOOL)hasChanges; 21 | 22 | /// Force an update to start 23 | - (void)update; 24 | 25 | - (id<IGListUpdateTransactable>)transaction; 26 | - (IGListUpdateTransactionBuilder *)transactionBuilder; 27 | - (IGListUpdateTransactionBuilder *)lastTransactionBuilder; 28 | 29 | @end 30 | 31 | NS_ASSUME_NONNULL_END 32 | -------------------------------------------------------------------------------- /Source/IGListKit/Internal/IGListArrayUtilsInternal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | @protocol IGListDiffable; 11 | 12 | /// Returns a copy of the provided array, with all duplicates 13 | /// of objects with the same `diffIdentifier` value removed. 14 | /// - Parameter objects: The list of diffable objects to filter. 15 | NSArray *objectsWithDuplicateIdentifiersRemoved(NSArray<id<IGListDiffable>> *objects); 16 | -------------------------------------------------------------------------------- /Source/IGListKit/Internal/IGListBatchUpdateData+DebugDescription.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <UIKit/UIKit.h> 9 | 10 | #if !__has_include(<IGListDiffKit/IGListDiffKit.h>) 11 | #import "IGListBatchUpdateData.h" 12 | #else 13 | #import <IGListDiffKit/IGListBatchUpdateData.h> 14 | #endif 15 | 16 | @interface IGListBatchUpdateData (DebugDescription) 17 | 18 | - (NSArray<NSString *> *)debugDescriptionLines; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /Source/IGListKit/Internal/IGListBatchUpdateState.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | typedef NS_ENUM (NSInteger, IGListBatchUpdateState) { 11 | IGListBatchUpdateStateIdle, 12 | IGListBatchUpdateStateQueuedBatchUpdate, 13 | IGListBatchUpdateStateExecutingBatchUpdateBlock, 14 | IGListBatchUpdateStateExecutedBatchUpdateBlock, 15 | }; 16 | -------------------------------------------------------------------------------- /Source/IGListKit/Internal/IGListBindingSectionController+DebugDescription.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "IGListBindingSectionController.h" 9 | 10 | @interface IGListBindingSectionController (DebugDescription) 11 | 12 | - (NSArray<NSString *> *)debugDescriptionLines; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Source/IGListKit/Internal/IGListCollectionViewLayoutInternal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <UIKit/UIScreen.h> 9 | 10 | static inline CGRect IGListRectIntegralScaled(CGRect rect) { 11 | CGFloat scale = [[UIScreen mainScreen] scale]; 12 | return CGRectMake(floor(rect.origin.x * scale) / scale, 13 | floor(rect.origin.y * scale) / scale, 14 | ceil(rect.size.width * scale) / scale, 15 | ceil(rect.size.height * scale) / scale); 16 | } 17 | -------------------------------------------------------------------------------- /Source/IGListKit/Internal/IGListDataSourceChangeTransaction.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | #if !__has_include(<IGListDiffKit/IGListDiffKit.h>) 11 | #import "IGListMacros.h" 12 | #else 13 | #import <IGListDiffKit/IGListMacros.h> 14 | #endif 15 | 16 | #import "IGListUpdatingDelegate.h" 17 | 18 | #import "IGListUpdateTransactable.h" 19 | 20 | NS_ASSUME_NONNULL_BEGIN 21 | 22 | /// Handles a `UICollectionView` `dataSource` change 23 | IGLK_SUBCLASSING_RESTRICTED 24 | @interface IGListDataSourceChangeTransaction : NSObject <IGListUpdateTransactable> 25 | 26 | - (instancetype)initWithChangeBlock:(IGListDataSourceChangeBlock)block 27 | itemUpdateBlocks:(NSArray<IGListItemUpdateBlock> *)itemUpdateBlocks 28 | completionBlocks:(NSArray<IGListUpdatingCompletion> *)completionBlocks NS_DESIGNATED_INITIALIZER; 29 | 30 | - (instancetype)init NS_UNAVAILABLE; 31 | + (instancetype)new NS_UNAVAILABLE; 32 | 33 | @end 34 | 35 | NS_ASSUME_NONNULL_END 36 | -------------------------------------------------------------------------------- /Source/IGListKit/Internal/IGListDebugger.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | #if !__has_include(<IGListDiffKit/IGListDiffKit.h>) 11 | #import "IGListMacros.h" 12 | #else 13 | #import <IGListDiffKit/IGListMacros.h> 14 | #endif 15 | 16 | @class IGListAdapter; 17 | 18 | IGLK_SUBCLASSING_RESTRICTED 19 | @interface IGListDebugger : NSObject 20 | 21 | + (void)trackAdapter:(IGListAdapter *)adapter; 22 | 23 | + (NSArray<NSString *> *)adapterDescriptions; 24 | 25 | + (void)clear; 26 | 27 | + (NSString *)dump; 28 | 29 | - (instancetype)init NS_UNAVAILABLE; 30 | + (instancetype)new NS_UNAVAILABLE; 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /Source/IGListKit/Internal/IGListDebugger.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "IGListDebugger.h" 9 | 10 | #import "IGListAdapter+DebugDescription.h" 11 | 12 | @implementation IGListDebugger 13 | 14 | static NSHashTable<IGListAdapter *> *livingAdaptersTable = nil; 15 | 16 | + (void)trackAdapter:(IGListAdapter *)adapter { 17 | #if defined(IGLK_DEBUG_DESCRIPTION_ENABLED) && IGLK_DEBUG_DESCRIPTION_ENABLED 18 | if (livingAdaptersTable == nil) { 19 | livingAdaptersTable = [NSHashTable weakObjectsHashTable]; 20 | } 21 | [livingAdaptersTable addObject:adapter]; 22 | #endif // #if IGLK_DEBUG_DESCRIPTION_ENABLED 23 | } 24 | 25 | + (NSArray<NSString *> *)adapterDescriptions { 26 | NSMutableArray *descriptions = [NSMutableArray new]; 27 | for (IGListAdapter *adapter in livingAdaptersTable) { 28 | [descriptions addObject:[adapter debugDescription]]; 29 | } 30 | return descriptions; 31 | } 32 | 33 | + (void)clear { 34 | [livingAdaptersTable removeAllObjects]; 35 | } 36 | 37 | + (NSString *)dump { 38 | return [[self adapterDescriptions] componentsJoinedByString:@"\n"]; 39 | } 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /Source/IGListKit/Internal/IGListDebuggingUtilities.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | 11 | NSString *IGListDebugBOOL(BOOL b); 12 | 13 | NSArray<NSString *> *IGListDebugIndentedLines(NSArray<NSString *> *lines); 14 | -------------------------------------------------------------------------------- /Source/IGListKit/Internal/IGListDebuggingUtilities.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "IGListDebuggingUtilities.h" 9 | 10 | NSString *IGListDebugBOOL(BOOL b) { 11 | return b ? @"Yes" : @"No"; 12 | } 13 | 14 | NSArray<NSString *> *IGListDebugIndentedLines(NSArray<NSString *> *lines) { 15 | NSMutableArray *newLines = [NSMutableArray new]; 16 | for (NSString *line in lines) { 17 | [newLines addObject:[NSString stringWithFormat:@" %@", line]]; 18 | } 19 | return newLines; 20 | } 21 | -------------------------------------------------------------------------------- /Source/IGListKit/Internal/IGListDefaultExperiments.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | #if __has_include(<IGListDiffKit/IGListDiffKit.h>) 11 | #import <IGListDiffKit/IGListExperiments.h> 12 | #else 13 | #import "IGListExperiments.h" 14 | #endif 15 | 16 | /// Provides a list of experiments that are enabled by default in IGListKit. 17 | static inline IGListExperiment IGListDefaultExperiments(void) { 18 | return IGListExperimentThrowOnInconsistencyException; 19 | } 20 | -------------------------------------------------------------------------------- /Source/IGListKit/Internal/IGListItemUpdatesCollector.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | #if !__has_include(<IGListDiffKit/IGListDiffKit.h>) 11 | #import "IGListMacros.h" 12 | #else 13 | #import <IGListDiffKit/IGListMacros.h> 14 | #endif 15 | 16 | @class IGListMoveIndexPath; 17 | @class IGListReloadIndexPath; 18 | 19 | /// Object to collect item updates. 20 | IGLK_SUBCLASSING_RESTRICTED 21 | @interface IGListItemUpdatesCollector : NSObject 22 | 23 | @property (nonatomic, strong, readonly) NSMutableIndexSet *sectionReloads; 24 | @property (nonatomic, strong, readonly) NSMutableArray<NSIndexPath *> *itemInserts; 25 | @property (nonatomic, strong, readonly) NSMutableArray<NSIndexPath *> *itemDeletes; 26 | @property (nonatomic, strong, readonly) NSMutableArray<IGListReloadIndexPath *> *itemReloads; 27 | @property (nonatomic, strong, readonly) NSMutableArray<IGListMoveIndexPath *> *itemMoves; 28 | 29 | - (BOOL)hasChanges; 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /Source/IGListKit/Internal/IGListItemUpdatesCollector.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "IGListItemUpdatesCollector.h" 9 | 10 | @implementation IGListItemUpdatesCollector 11 | 12 | - (instancetype)init { 13 | if (self = [super init]) { 14 | _sectionReloads = [NSMutableIndexSet new]; 15 | _itemInserts = [NSMutableArray new]; 16 | _itemMoves = [NSMutableArray new]; 17 | _itemDeletes = [NSMutableArray new]; 18 | _itemReloads = [NSMutableArray new]; 19 | } 20 | return self; 21 | } 22 | 23 | - (BOOL)hasChanges { 24 | return [self.sectionReloads count] > 0 25 | || [self.itemInserts count] > 0 26 | || [self.itemMoves count] > 0 27 | || [self.itemReloads count] > 0 28 | || [self.itemDeletes count] > 0; 29 | } 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /Source/IGListKit/Internal/IGListReloadIndexPath.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "IGListReloadIndexPath.h" 9 | 10 | @implementation IGListReloadIndexPath 11 | 12 | - (instancetype)initWithFromIndexPath:(NSIndexPath *)fromIndexPath 13 | toIndexPath:(NSIndexPath *)toIndexPath { 14 | if (self = [super init]) { 15 | _fromIndexPath = fromIndexPath; 16 | _toIndexPath = toIndexPath; 17 | } 18 | return self; 19 | } 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Source/IGListKit/Internal/IGListSectionMap+DebugDescription.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | #import "IGListSectionMap.h" 11 | 12 | @interface IGListSectionMap (DebugDescription) 13 | 14 | - (NSArray<NSString *> *)debugDescriptionLines; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Source/IGListKit/Internal/IGListViewVisibilityTrackerInternal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "IGListViewVisibilityTracker.h" 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | @interface IGListViewVisibilityTracker() 13 | 14 | /// Date the tracker is created 15 | @property (nonatomic, strong, readwrite) NSDate *dateCreated; 16 | 17 | /// When evaluating the state, compare the `dateCreated` to this one. If nil, we use `now` 18 | @property (nonatomic, strong, readwrite, nullable) NSDate *comparedDateOverride; 19 | 20 | /// What we consider as early. Default is 1 second. 21 | @property (nonatomic, assign, readwrite) NSTimeInterval earlyTimeInterval; 22 | 23 | @end 24 | 25 | NS_ASSUME_NONNULL_END 26 | -------------------------------------------------------------------------------- /Source/IGListKit/Internal/UICollectionView+DebugDescription.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <UIKit/UIKit.h> 9 | 10 | @interface UICollectionView (DebugDescription) 11 | 12 | - (NSArray<NSString *> *)debugDescriptionLines; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Source/IGListKit/Internal/UICollectionView+IGListBatchUpdateData.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <UIKit/UIKit.h> 9 | 10 | @class IGListBatchUpdateData; 11 | 12 | @interface UICollectionView (IGListBatchUpdateData) 13 | 14 | - (void)ig_applyBatchUpdateData:(IGListBatchUpdateData *)updateData; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Source/IGListKit/Internal/UICollectionView+IGListBatchUpdateData.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "UICollectionView+IGListBatchUpdateData.h" 9 | 10 | #if !__has_include(<IGListDiffKit/IGListDiffKit.h>) 11 | #import "IGListBatchUpdateData.h" 12 | #else 13 | #import <IGListDiffKit/IGListBatchUpdateData.h> 14 | #endif 15 | 16 | @implementation UICollectionView (IGListBatchUpdateData) 17 | 18 | - (void)ig_applyBatchUpdateData:(IGListBatchUpdateData *)updateData { 19 | [self deleteItemsAtIndexPaths:updateData.deleteIndexPaths]; 20 | [self insertItemsAtIndexPaths:updateData.insertIndexPaths]; 21 | [self reloadItemsAtIndexPaths:updateData.updateIndexPaths]; 22 | 23 | for (IGListMoveIndexPath *move in updateData.moveIndexPaths) { 24 | [self moveItemAtIndexPath:move.from toIndexPath:move.to]; 25 | } 26 | 27 | for (IGListMoveIndex *move in updateData.moveSections) { 28 | [self moveSection:move.from toSection:move.to]; 29 | } 30 | 31 | [self deleteSections:updateData.deleteSections]; 32 | [self insertSections:updateData.insertSections]; 33 | } 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /Source/IGListKit/Internal/UICollectionViewLayout+InteractiveReordering.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <UIKit/UIKit.h> 9 | 10 | #import "IGListAdapter.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface UICollectionViewLayout (InteractiveReordering) 15 | 16 | - (void)ig_hijackLayoutInteractiveReorderingMethodForAdapter:(IGListAdapter *)adapter; 17 | 18 | - (nullable NSIndexPath *)updatedTargetForInteractivelyMovingItem:(NSIndexPath *)previousIndexPath 19 | toIndexPath:(NSIndexPath *)originalTarget 20 | adapter:(IGListAdapter *)adapter; 21 | 22 | @end 23 | 24 | NS_ASSUME_NONNULL_END 25 | -------------------------------------------------------------------------------- /Source/IGListKit/Internal/UIScrollView+IGListKit.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <UIKit/UIKit.h> 9 | 10 | @interface UIScrollView (IGListKit) 11 | 12 | - (UIEdgeInsets) ig_contentInset; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Source/IGListKit/Internal/UIScrollView+IGListKit.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "UIScrollView+IGListKit.h" 9 | 10 | @implementation UIScrollView (IGListKit) 11 | 12 | - (UIEdgeInsets) ig_contentInset 13 | { 14 | UIEdgeInsets contentInset = self.contentInset; 15 | if (@available(iOS 11.0, tvOS 11.0, *)) { 16 | contentInset = self.adjustedContentInset; 17 | } 18 | return contentInset; 19 | } 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Source/IGListKit/Internal/UIViewController+IGListAdapterInternal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "UIViewController+IGListAdapter.h" 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | @interface UIViewController (IGListAdapterInternal) 13 | 14 | - (void)associateListAdapter:(IGListAdapter *)adapter; 15 | 16 | @end 17 | 18 | NS_ASSUME_NONNULL_END 19 | -------------------------------------------------------------------------------- /Source/IGListKit/UIViewController+IGListAdapter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <UIKit/UIKit.h> 9 | 10 | @class IGListAdapter; 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface UIViewController (IGListAdapter) 15 | 16 | /// Adapters that have this VC as their `viewController` 17 | - (NSArray<IGListAdapter *> *)associatedListAdapters; 18 | 19 | @end 20 | 21 | NS_ASSUME_NONNULL_END 22 | -------------------------------------------------------------------------------- /Source/IGListKit/UIViewController+IGListAdapter.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "UIViewController+IGListAdapter.h" 9 | 10 | #import <objc/runtime.h> 11 | 12 | @implementation UIViewController (IGListAdapter) 13 | 14 | - (NSArray<IGListAdapter *> *)associatedListAdapters { 15 | return [[self _associatedListAdaptersTable] allObjects]; 16 | } 17 | 18 | - (void)associateListAdapter:(IGListAdapter *)adapter { 19 | NSHashTable *const table = [self _associatedListAdaptersTable]; 20 | [table addObject:adapter]; 21 | } 22 | 23 | - (NSHashTable *)_associatedListAdaptersTable { 24 | NSHashTable *table = objc_getAssociatedObject(self, @selector(_associatedListAdaptersTable)); 25 | if (table) { 26 | return table; 27 | } 28 | 29 | table = [NSHashTable weakObjectsHashTable]; 30 | objc_setAssociatedObject(self, @selector(_associatedListAdaptersTable), table, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 31 | return table; 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /Source/IGListSwiftKit/IGListSwiftKit.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | //! Project version number for IGListSwiftKit. 11 | FOUNDATION_EXPORT double IGListSwiftKitVersionNumber; 12 | 13 | //! Project version string for IGListSwiftKit. 14 | FOUNDATION_EXPORT const unsigned char IGListSwiftKitVersionString[]; 15 | -------------------------------------------------------------------------------- /Source/Info.plist: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 3 | <plist version="1.0"> 4 | <dict> 5 | <key>CFBundleDevelopmentRegion</key> 6 | <string>$(DEVELOPMENT_LANGUAGE)</string> 7 | <key>CFBundleExecutable</key> 8 | <string>$(EXECUTABLE_NAME)</string> 9 | <key>CFBundleIdentifier</key> 10 | <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> 11 | <key>CFBundleInfoDictionaryVersion</key> 12 | <string>6.0</string> 13 | <key>CFBundleName</key> 14 | <string>$(PRODUCT_NAME)</string> 15 | <key>CFBundlePackageType</key> 16 | <string>FMWK</string> 17 | <key>CFBundleShortVersionString</key> 18 | <string>5.0.0</string> 19 | <key>CFBundleVersion</key> 20 | <string>$(CURRENT_PROJECT_VERSION)</string> 21 | <key>NSPrincipalClass</key> 22 | <string></string> 23 | </dict> 24 | </plist> 25 | -------------------------------------------------------------------------------- /Tests/IGListDiffTests.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <XCTest/XCTest.h> 9 | 10 | // Exposed for internal benchmark tests 11 | @interface IGListDiffTests : XCTestCase 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Tests/IGListGenericSectionControllerTests.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <XCTest/XCTest.h> 9 | 10 | #import <IGListKit/IGListGenericSectionController.h> 11 | 12 | @interface IGListGenericSectionControllerTests : XCTestCase 13 | 14 | @end 15 | 16 | @implementation IGListGenericSectionControllerTests 17 | 18 | - (void)test_whenUpdatingToObject_thatSameObjectIsStored { 19 | IGListGenericSectionController<NSString *> *controller = [IGListGenericSectionController new]; 20 | NSString *foo = @"foo"; 21 | [controller didUpdateToObject:foo]; 22 | XCTAssertEqual(controller.object, foo); 23 | } 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /Tests/IGListKitTests-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <IGListKit/IGListKit.h> 9 | -------------------------------------------------------------------------------- /Tests/Info.plist: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 3 | <plist version="1.0"> 4 | <dict> 5 | <key>CFBundleDevelopmentRegion</key> 6 | <string>$(DEVELOPMENT_LANGUAGE)</string> 7 | <key>CFBundleExecutable</key> 8 | <string>$(EXECUTABLE_NAME)</string> 9 | <key>CFBundleIdentifier</key> 10 | <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> 11 | <key>CFBundleInfoDictionaryVersion</key> 12 | <string>6.0</string> 13 | <key>CFBundleName</key> 14 | <string>$(PRODUCT_NAME)</string> 15 | <key>CFBundlePackageType</key> 16 | <string>BNDL</string> 17 | <key>CFBundleShortVersionString</key> 18 | <string>1.0</string> 19 | <key>CFBundleVersion</key> 20 | <string>1</string> 21 | </dict> 22 | </plist> 23 | -------------------------------------------------------------------------------- /Tests/Objects/IGLayoutTestDataSource.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <UIKit/UIKit.h> 9 | 10 | @class IGLayoutTestSection; 11 | 12 | @interface IGLayoutTestDataSource : NSObject <UICollectionViewDelegateFlowLayout, UICollectionViewDataSource> 13 | 14 | @property (nonatomic, copy) NSArray<IGLayoutTestSection *> *sections; 15 | 16 | // call before using as the data source so cells and headers are configured 17 | - (void)configCollectionView:(UICollectionView *)collectionView; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Tests/Objects/IGLayoutTestItem.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <UIKit/UIKit.h> 9 | 10 | #define genLayoutTestItem(s) [[IGLayoutTestItem alloc] initWithSize:s] 11 | 12 | @interface IGLayoutTestItem : NSObject 13 | 14 | @property (nonatomic, assign, readonly) CGSize size; 15 | 16 | - (instancetype)initWithSize:(CGSize)size; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Tests/Objects/IGLayoutTestItem.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "IGLayoutTestItem.h" 9 | 10 | @implementation IGLayoutTestItem 11 | 12 | - (instancetype)initWithSize:(CGSize)size { 13 | if (self = [super init]) { 14 | _size = size; 15 | } 16 | return self; 17 | } 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Tests/Objects/IGListAdapterUpdateTester.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | #import <IGListKit/IGListAdapterUpdateListener.h> 11 | 12 | @interface IGListAdapterUpdateTester : NSObject <IGListAdapterUpdateListener> 13 | 14 | @property (nonatomic, assign) NSInteger hits; 15 | @property (nonatomic, assign) IGListAdapterUpdateType type; 16 | @property (nonatomic, assign) BOOL animated; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Tests/Objects/IGListAdapterUpdateTester.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "IGListAdapterUpdateTester.h" 9 | 10 | @implementation IGListAdapterUpdateTester 11 | 12 | - (void)listAdapter:(IGListAdapter *)listAdapter didFinishUpdate:(IGListAdapterUpdateType)update animated:(BOOL)animated { 13 | self.hits++; 14 | self.type = update; 15 | self.animated = animated; 16 | } 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Tests/Objects/IGListTestAdapterDataSource.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | #import <IGListKit/IGListAdapterDataSource.h> 11 | 12 | #import "IGListTestCase.h" 13 | 14 | @interface IGListTestAdapterDataSource : NSObject <IGListTestCaseDataSource> 15 | 16 | // array of numbers which is then passed to -[IGListTestSection setItems:] 17 | @property (nonatomic, copy) NSArray <NSNumber *> *objects; 18 | 19 | @property (nonatomic, strong) UIView *backgroundView; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Tests/Objects/IGListTestAdapterDataSource.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "IGListTestAdapterDataSource.h" 9 | 10 | #import <IGListKit/IGListAdapter.h> 11 | 12 | #import "IGListTestContainerSizeSection.h" 13 | #import "IGListTestSection.h" 14 | 15 | @implementation IGListTestAdapterDataSource 16 | 17 | - (NSArray *)objectsForListAdapter:(IGListAdapter *)listAdapter { 18 | return self.objects; 19 | } 20 | 21 | - (IGListSectionController *)listAdapter:(IGListAdapter *)listAdapter sectionControllerForObject:(id)object { 22 | if ([object isKindOfClass:[NSNumber class]]) { 23 | if ([(NSNumber*)object isEqual: @42]) { 24 | return [IGListTestContainerSizeSection new]; 25 | } 26 | return [IGListTestSection new]; 27 | } 28 | return nil; 29 | } 30 | 31 | - (nullable UIView *)emptyViewForListAdapter:(IGListAdapter *)listAdapter { 32 | return self.backgroundView; 33 | } 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /Tests/Objects/IGListTestAdapterHorizontalDataSource.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | #import <IGListKit/IGListAdapterDataSource.h> 11 | 12 | @interface IGListTestAdapterHorizontalDataSource : NSObject <IGListAdapterDataSource> 13 | 14 | // array of numbers which is then passed to -[IGListTestSection setItems:] 15 | @property (nonatomic, copy) NSArray <NSNumber *> *objects; 16 | 17 | @property (nonatomic, strong) UIView *backgroundView; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Tests/Objects/IGListTestAdapterHorizontalDataSource.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "IGListTestAdapterHorizontalDataSource.h" 9 | 10 | #import <IGListKit/IGListAdapter.h> 11 | 12 | #import "IGListTestHorizontalSection.h" 13 | 14 | @implementation IGListTestAdapterHorizontalDataSource 15 | 16 | - (NSArray *)objectsForListAdapter:(IGListAdapter *)listAdapter { 17 | return self.objects; 18 | } 19 | 20 | - (IGListSectionController *)listAdapter:(IGListAdapter *)listAdapter sectionControllerForObject:(id)object { 21 | IGListTestHorizontalSection *list = [[IGListTestHorizontalSection alloc] init]; 22 | return list; 23 | } 24 | 25 | - (nullable UIView *)emptyViewForListAdapter:(IGListAdapter *)listAdapter { 26 | return self.backgroundView; 27 | } 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /Tests/Objects/IGListTestAdapterReorderingDataSource.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | #import <IGListKit/IGListAdapterDataSource.h> 11 | #import <IGListKit/IGListAdapterMoveDelegate.h> 12 | 13 | #import "IGListTestCase.h" 14 | 15 | @interface IGListTestAdapterReorderingDataSource : NSObject <IGListTestCaseDataSource, IGListAdapterMoveDelegate> 16 | 17 | // array of numbers which is then passed to -[IGTestReorderableSection setItems:] 18 | @property (nonatomic, copy) NSArray <NSNumber *> *objects; 19 | 20 | @property (nonatomic, strong) UIView *backgroundView; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Tests/Objects/IGListTestAdapterReorderingDataSource.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "IGListTestAdapterReorderingDataSource.h" 9 | 10 | #import <IGListKit/IGListAdapter.h> 11 | 12 | #import "IGTestReorderableSection.h" 13 | 14 | @implementation IGListTestAdapterReorderingDataSource 15 | 16 | - (NSArray *)objectsForListAdapter:(IGListAdapter *)listAdapter { 17 | return self.objects; 18 | } 19 | 20 | - (IGListSectionController *)listAdapter:(IGListAdapter *)listAdapter sectionControllerForObject:(id)object { 21 | return [IGTestReorderableSection new]; 22 | } 23 | 24 | - (nullable UIView *)emptyViewForListAdapter:(nonnull IGListAdapter *)listAdapter { 25 | return self.backgroundView; 26 | } 27 | 28 | #pragma mark - IGListAdapterMoveDelegate 29 | 30 | - (void)listAdapter:(IGListAdapter *)listAdapter 31 | moveObject:(id)object 32 | from:(NSArray *)previousObjects 33 | to:(NSArray *)objects { 34 | self.objects = objects; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /Tests/Objects/IGListTestAdapterStoryboardDataSource.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | #import <IGListKit/IGListAdapterDataSource.h> 11 | 12 | @interface IGListTestAdapterStoryboardDataSource : NSObject <IGListAdapterDataSource> 13 | 14 | // array of numbers which is then passed to -[IGListTestSection setItems:] 15 | @property (nonatomic, copy) NSArray <NSNumber *> *objects; 16 | 17 | @property (nonatomic, strong) UIView *backgroundView; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Tests/Objects/IGListTestAdapterStoryboardDataSource.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "IGListTestAdapterStoryboardDataSource.h" 9 | 10 | #import <IGListKit/IGListAdapter.h> 11 | 12 | #import "IGListTestStoryboardSection.h" 13 | 14 | @implementation IGListTestAdapterStoryboardDataSource 15 | 16 | - (NSArray *)objectsForListAdapter:(IGListAdapter *)listAdapter { 17 | return self.objects; 18 | } 19 | 20 | - (IGListSectionController *)listAdapter:(IGListAdapter *)listAdapter sectionControllerForObject:(id)object { 21 | IGListTestStoryboardSection *list = [[IGListTestStoryboardSection alloc] init]; 22 | return list; 23 | } 24 | 25 | - (nullable UIView *)emptyViewForListAdapter:(IGListAdapter *)listAdapter { 26 | return self.backgroundView; 27 | } 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /Tests/Objects/IGListTestCollectionViewLayout.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <UIKit/UIKit.h> 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | /// Layout that 1) creates all attributes regardless of size, and 2) positions them with origin (0,0) 13 | @interface IGListTestCollectionViewLayout : UICollectionViewLayout 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Tests/Objects/IGListTestContainerSizeSection.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <UIKit/UIKit.h> 9 | 10 | #import <IGListKit/IGListSectionController.h> 11 | 12 | 13 | @interface IGListTestContainerSizeSection : IGListSectionController 14 | 15 | @property (nonatomic, assign) NSInteger items; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Tests/Objects/IGListTestHorizontalSection.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <UIKit/UIKit.h> 9 | 10 | #import <IGListKit/IGListSectionController.h> 11 | 12 | 13 | @interface IGListTestHorizontalSection : IGListSectionController 14 | 15 | @property (nonatomic, assign) NSInteger items; 16 | 17 | @property (nonatomic, assign) BOOL wasSelected; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Tests/Objects/IGListTestHorizontalSection.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "IGListTestHorizontalSection.h" 9 | 10 | @implementation IGListTestHorizontalSection 11 | 12 | - (NSArray <Class> *)cellClasses { 13 | return @[UICollectionViewCell.class]; 14 | } 15 | 16 | - (NSInteger)numberOfItems { 17 | return self.items; 18 | } 19 | 20 | - (CGSize)sizeForItemAtIndex:(NSInteger)index { 21 | return CGSizeMake(10, 100); 22 | } 23 | 24 | - (UICollectionViewCell *)cellForItemAtIndex:(NSInteger)index { 25 | return [self.collectionContext dequeueReusableCellOfClass:UICollectionViewCell.class 26 | forSectionController:self 27 | atIndex:index]; 28 | } 29 | 30 | - (void)didUpdateToObject:(id)object { 31 | if ([object isKindOfClass:[NSNumber class]]) { 32 | self.items = [object integerValue]; 33 | } 34 | } 35 | 36 | - (void)didSelectItemAtIndex:(NSInteger)index { 37 | self.wasSelected = YES; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /Tests/Objects/IGListTestOffsettingLayout.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <UIKit/UIKit.h> 9 | 10 | @interface IGListTestOffsettingLayout : UICollectionViewFlowLayout 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Tests/Objects/IGListTestOffsettingLayout.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "IGListTestOffsettingLayout.h" 9 | 10 | @implementation IGListTestOffsettingLayout 11 | 12 | - (void)prepareLayout { 13 | [super prepareLayout]; 14 | self.collectionView.contentOffset = CGPointMake(0, 10); 15 | } 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Tests/Objects/IGListTestSection.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <UIKit/UIKit.h> 9 | 10 | #import <IGListKit/IGListSectionController.h> 11 | 12 | 13 | @interface IGListTestSection : IGListSectionController 14 | 15 | @property (nonatomic, assign) NSInteger items; 16 | @property (nonatomic, assign) CGSize size; 17 | @property (nonatomic, assign) BOOL wasSelected; 18 | @property (nonatomic, assign) BOOL wasDeselected; 19 | @property (nonatomic, assign) BOOL wasHighlighted; 20 | @property (nonatomic, assign) BOOL wasUnhighlighted; 21 | @property (nonatomic, assign) BOOL wasDisplayed; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Tests/Objects/IGListTestStoryboardSection.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <UIKit/UIKit.h> 9 | 10 | #import <IGListKit/IGListSectionController.h> 11 | 12 | 13 | @interface IGListTestStoryboardSection : IGListSectionController 14 | 15 | @property (nonatomic, assign) NSInteger items; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Tests/Objects/IGListTestStoryboardSection.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "IGListTestStoryboardSection.h" 9 | 10 | #import "IGTestStoryboardCell.h" 11 | 12 | @implementation IGListTestStoryboardSection 13 | 14 | - (NSInteger)numberOfItems { 15 | return self.items; 16 | } 17 | 18 | - (CGSize)sizeForItemAtIndex:(NSInteger)index { 19 | return CGSizeMake(100, 45); 20 | } 21 | 22 | - (UICollectionViewCell *)cellForItemAtIndex:(NSInteger)index { 23 | return [self.collectionContext dequeueReusableCellFromStoryboardWithIdentifier:@"IGTestStoryboardCell" 24 | forSectionController:self 25 | atIndex:index]; 26 | } 27 | 28 | - (void)didUpdateToObject:(id)object { 29 | if ([object isKindOfClass:[NSNumber class]]) { 30 | self.items = [object integerValue]; 31 | } 32 | } 33 | 34 | - (void)didSelectItemAtIndex:(NSInteger)index {} 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /Tests/Objects/IGListTestUICollectionViewDataSource.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <UIKit/UIKit.h> 9 | 10 | #import <IGListDiffKit/IGListDiffable.h> 11 | 12 | @interface IGSectionObject : NSObject <IGListDiffable> 13 | 14 | @property (nonatomic, copy) NSArray *objects; 15 | 16 | + (instancetype)sectionWithObjects:(NSArray *)objects; 17 | 18 | + (instancetype)sectionWithObjects:(NSArray *)objects identifier:(NSString *)identifier; 19 | 20 | /** 21 | @param usesIdentifierForDiffable YES if we only use the `identifier` for -isEqualToDiffableObject. NO then we compares both the `identifier` as well as `objects`. 22 | */ 23 | + (instancetype)sectionWithObjects:(NSArray *)objects identifier:(NSString *)identifier usesIdentifierForDiffable:(BOOL)usesIdentifierForDiffable; 24 | 25 | @end 26 | 27 | @interface IGListTestUICollectionViewDataSource : NSObject <UICollectionViewDataSource> 28 | 29 | @property (nonatomic, copy) NSArray <IGSectionObject *> *sections; 30 | 31 | - (instancetype)initWithCollectionView:(UICollectionView *)collectionView; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /Tests/Objects/IGTestBindingSingleItemDataSource.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import <Foundation/Foundation.h> 11 | 12 | #import <IGListKit/IGListAdapterDataSource.h> 13 | 14 | #import "IGTestObject.h" 15 | #import "IGListTestCase.h" 16 | 17 | NS_ASSUME_NONNULL_BEGIN 18 | 19 | @interface IGTestBindingSingleItemDataSource : NSObject <IGListTestCaseDataSource> 20 | 21 | @property (nonatomic, strong) NSArray<IGTestObject *> *objects; 22 | 23 | @end 24 | 25 | NS_ASSUME_NONNULL_END 26 | -------------------------------------------------------------------------------- /Tests/Objects/IGTestBindingWithoutDeselectionDelegate.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | #import <IGListKit/IGListKit.h> 11 | 12 | @interface IGTestBindingWithoutDeselectionDelegate : NSObject <IGListBindingSectionControllerSelectionDelegate> 13 | 14 | @property (nonatomic, assign) BOOL selected; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Tests/Objects/IGTestBindingWithoutDeselectionDelegate.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "IGTestBindingWithoutDeselectionDelegate.h" 9 | 10 | @implementation IGTestBindingWithoutDeselectionDelegate 11 | 12 | - (void)sectionController:(IGListBindingSectionController *)sectionController 13 | didSelectItemAtIndex:(NSInteger)index 14 | viewModel:(id)viewModel { 15 | self.selected = YES; 16 | } 17 | 18 | - (void)sectionController:(IGListBindingSectionController *)sectionController 19 | didDeselectItemAtIndex:(NSInteger)index 20 | viewModel:(id)viewModel; { 21 | } 22 | 23 | - (void)sectionController:(nonnull IGListBindingSectionController *)sectionController 24 | didHighlightItemAtIndex:(NSInteger)index 25 | viewModel:(nonnull id)viewModel { 26 | } 27 | 28 | 29 | - (void)sectionController:(nonnull IGListBindingSectionController *)sectionController 30 | didUnhighlightItemAtIndex:(NSInteger)index 31 | viewModel:(nonnull id)viewModel { 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /Tests/Objects/IGTestCell.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <UIKit/UIKit.h> 9 | 10 | #import <IGListKit/IGListBindable.h> 11 | 12 | @interface IGTestCell : UICollectionViewCell <IGListBindable> 13 | 14 | @property (nonatomic, weak) id delegate; 15 | @property (nonatomic, strong) IBOutlet UILabel *label; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Tests/Objects/IGTestCell.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "IGTestCell.h" 9 | 10 | #import "IGTestObject.h" 11 | 12 | @implementation IGTestCell 13 | 14 | - (instancetype)initWithFrame:(CGRect)frame { 15 | if (self = [super initWithFrame:frame]) { 16 | _label = [[UILabel alloc] init]; 17 | [self.contentView addSubview:_label]; 18 | } 19 | return self; 20 | } 21 | 22 | - (void)bindViewModel:(id)viewModel { 23 | IGTestObject *object = viewModel; 24 | self.label.text = [object.value description]; 25 | } 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /Tests/Objects/IGTestDelegateDataSource.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | #import <IGListKit/IGListAdapterDataSource.h> 11 | 12 | #import "IGListTestCase.h" 13 | #import "IGTestCell.h" 14 | 15 | @class IGTestDelegateController; 16 | @class IGTestObject; 17 | 18 | extern NSObject *const kIGTestDelegateDataSourceSkipObject; 19 | extern NSObject *const kIGTestDelegateDataSourceNoSectionControllerSubclass; 20 | 21 | @interface IGTestDelegateDataSource : NSObject <IGListTestCaseDataSource> 22 | 23 | @property (nonatomic, copy) NSArray <IGTestObject *> *objects; 24 | 25 | @property (nonatomic, copy) void (^cellConfigureBlock)(IGTestDelegateController *); 26 | 27 | @property (nonatomic, strong) IGTestCell *overrideCell; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /Tests/Objects/IGTestDiffingDataSource.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | #import <IGListKit/IGListAdapterDataSource.h> 11 | 12 | #import "IGListTestCase.h" 13 | 14 | @class IGTestDiffingObject; 15 | 16 | @interface IGTestDiffingDataSource : NSObject <IGListTestCaseDataSource> 17 | 18 | @property (nonatomic, copy) NSArray<IGTestDiffingObject *> *objects; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /Tests/Objects/IGTestDiffingDataSource.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "IGTestDiffingDataSource.h" 9 | 10 | #import "IGTestDiffingObject.h" 11 | #import "IGTestDiffingSectionController.h" 12 | 13 | @implementation IGTestDiffingDataSource 14 | 15 | #pragma mark - IGListAdapterDataSource 16 | 17 | - (NSArray<id<IGListDiffable>> *)objectsForListAdapter:(IGListAdapter *)listAdapter { 18 | return self.objects; 19 | } 20 | 21 | - (IGListSectionController *)listAdapter:(IGListAdapter *)listAdapter sectionControllerForObject:(id)object { 22 | return [IGTestDiffingSectionController new]; 23 | } 24 | 25 | - (UIView *)emptyViewForListAdapter:(IGListAdapter *)listAdapter { return nil; } 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /Tests/Objects/IGTestDiffingObject.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | #import <IGListDiffKit/IGListDiffable.h> 11 | 12 | @interface IGTestDiffingObject : NSObject<IGListDiffable> 13 | 14 | - (instancetype)initWithKey:(id)key objects:(NSArray *)objects; 15 | 16 | @property (nonatomic, strong, readonly) id key; 17 | @property (nonatomic, strong, readonly) NSArray *objects; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Tests/Objects/IGTestDiffingSectionController.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <IGListKit/IGListKit.h> 9 | 10 | @interface IGTestDiffingSectionController : IGListBindingSectionController <IGListBindingSectionControllerDataSource, IGListBindingSectionControllerSelectionDelegate> 11 | 12 | @property (nonatomic, strong) id selectedViewModel; 13 | @property (nonatomic, strong) id deselectedViewModel; 14 | @property (nonatomic, strong) id highlightedViewModel; 15 | @property (nonatomic, strong) id unhighlightedViewModel; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Tests/Objects/IGTestInvalidateLayoutDataSource.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | #import <IGListKit/IGListAdapterDataSource.h> 11 | 12 | #import "IGListTestCase.h" 13 | 14 | @class IGTestInvalidateLayoutObject; 15 | 16 | @interface IGTestInvalidateLayoutDataSource : NSObject <IGListTestCaseDataSource> 17 | 18 | @property (nonatomic, copy) NSArray<IGTestInvalidateLayoutObject *> *objects; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /Tests/Objects/IGTestInvalidateLayoutDataSource.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "IGTestInvalidateLayoutDataSource.h" 9 | 10 | #import "IGTestInvalidateLayoutObject.h" 11 | #import "IGTestInvalidateLayoutSectionController.h" 12 | 13 | @implementation IGTestInvalidateLayoutDataSource 14 | 15 | #pragma mark - IGListAdapterDataSource 16 | 17 | - (NSArray<id<IGListDiffable>> *)objectsForListAdapter:(IGListAdapter *)listAdapter { 18 | return self.objects; 19 | } 20 | 21 | - (IGListSectionController *)listAdapter:(IGListAdapter *)listAdapter sectionControllerForObject:(id)object { 22 | return [IGTestInvalidateLayoutSectionController new]; 23 | } 24 | 25 | - (UIView *)emptyViewForListAdapter:(IGListAdapter *)listAdapter { return nil; } 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /Tests/Objects/IGTestInvalidateLayoutObject.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | #import <IGListDiffKit/IGListDiffable.h> 11 | 12 | #import "IGLayoutTestItem.h" 13 | #import "IGTestObject.h" 14 | 15 | #define genInvalidateLayoutObject(key, size) [[IGTestObject alloc] initWithKey:key value:[[IGLayoutTestItem alloc] initWithSize:size]] 16 | 17 | @interface IGTestInvalidateLayoutObject : NSObject<IGListDiffable> 18 | 19 | - (instancetype)initWithKey:(id)key objects:(NSArray<IGTestObject *> *)objects; 20 | 21 | @property (nonatomic, strong, readonly) id key; 22 | @property (nonatomic, strong, readonly) NSArray<IGTestObject *> *objects; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Tests/Objects/IGTestInvalidateLayoutObject.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "IGTestInvalidateLayoutObject.h" 9 | 10 | @implementation IGTestInvalidateLayoutObject 11 | 12 | - (instancetype)initWithKey:(id)key objects:(NSArray *)objects { 13 | if (self = [super init]) { 14 | _key = key; 15 | _objects = objects; 16 | } 17 | return self; 18 | } 19 | 20 | - (NSString *)description { 21 | return [NSString stringWithFormat:@"<%@: %p; key: %@; objects: %@>", 22 | NSStringFromClass(self.class), self, self.key, self.objects]; 23 | } 24 | 25 | #pragma mark - IGListDiffable 26 | 27 | - (id<NSObject>)diffIdentifier { 28 | return self.key; 29 | } 30 | 31 | - (BOOL)isEqualToDiffableObject:(id)object { 32 | if (object == self) { 33 | return YES; 34 | } 35 | if ([object isKindOfClass:[IGTestInvalidateLayoutObject class]]) { 36 | return YES; 37 | } 38 | 39 | return NO; 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /Tests/Objects/IGTestInvalidateLayoutSectionController.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <IGListKit/IGListKit.h> 9 | 10 | @interface IGTestInvalidateLayoutSectionController : IGListBindingSectionController <IGListBindingSectionControllerDataSource> 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Tests/Objects/IGTestNibSupplementaryView.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <UIKit/UIKit.h> 9 | 10 | @interface IGTestNibSupplementaryView : UICollectionViewCell 11 | 12 | @property (nonatomic, weak) id delegate; 13 | 14 | @property (nonatomic, strong) IBOutlet UILabel *label; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Tests/Objects/IGTestNibSupplementaryView.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "IGTestNibSupplementaryView.h" 9 | 10 | @implementation IGTestNibSupplementaryView 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Tests/Objects/IGTestNumberBindableCell.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <UIKit/UIKit.h> 9 | 10 | #import <IGListKit/IGListBindable.h> 11 | 12 | @interface IGTestNumberBindableCell : UICollectionViewCell<IGListBindable> 13 | 14 | @property (nonatomic, strong, readonly) UITextField *textField; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Tests/Objects/IGTestNumberBindableCell.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "IGTestNumberBindableCell.h" 9 | 10 | @implementation IGTestNumberBindableCell 11 | 12 | - (instancetype)initWithFrame:(CGRect)frame { 13 | if (self = [super initWithFrame:frame]) { 14 | _textField = [UITextField new]; 15 | } 16 | return self; 17 | } 18 | 19 | #pragma mark - IGListBindable 20 | 21 | - (void)bindViewModel:(id)viewModel { 22 | self.textField.text = [viewModel description]; 23 | } 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /Tests/Objects/IGTestObject.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | #import <IGListKit/IGListKit.h> 11 | 12 | #define genTestObject(k, v) [[IGTestObject alloc] initWithKey:k value:v] 13 | 14 | @interface IGTestObject : NSObject <IGListDiffable, NSCopying> 15 | 16 | - (instancetype)initWithKey:(id <NSCopying>)key value:(id)value; 17 | 18 | @property (nonatomic, strong, readonly) id key; 19 | @property (nonatomic, strong) id value; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Tests/Objects/IGTestObject.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "IGTestObject.h" 9 | 10 | @implementation IGTestObject 11 | 12 | - (instancetype)initWithKey:(id)key value:(id)value { 13 | if (self = [super init]) { 14 | _key = [key copy]; 15 | _value = value; 16 | } 17 | return self; 18 | } 19 | 20 | - (instancetype)copyWithZone:(NSZone *)zone { 21 | return [[IGTestObject alloc] initWithKey:self.key value:self.value]; 22 | } 23 | 24 | 25 | #pragma mark - IGListDiffable 26 | 27 | - (id<NSObject>)diffIdentifier { 28 | return self.key; 29 | } 30 | 31 | - (BOOL)isEqualToDiffableObject:(id)object { 32 | if (object == self) { 33 | return YES; 34 | } 35 | if ([object isKindOfClass:[IGTestObject class]]) { 36 | id k1 = self.key; 37 | id k2 = [object key]; 38 | id v1 = self.value; 39 | id v2 = [(IGTestObject *)object value]; 40 | return (v1 == v2 || [v1 isEqual:v2]) && (k1 == k2 || [k1 isEqual:k2]); 41 | } 42 | return NO; 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /Tests/Objects/IGTestReorderableSection.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <UIKit/UIKit.h> 9 | 10 | #import <IGListDiffKit/IGListDiffable.h> 11 | #import <IGListKit/IGListSectionController.h> 12 | 13 | @interface IGTestReorderableSectionObject : NSObject <IGListDiffable> 14 | 15 | @property (nonatomic, copy) NSArray *objects; 16 | 17 | + (instancetype)sectionWithObjects:(NSArray *)objects; 18 | 19 | @end 20 | 21 | @interface IGTestReorderableSection : IGListSectionController 22 | 23 | @property (nonatomic, strong) IGTestReorderableSectionObject *sectionObject; 24 | @property (nonatomic, assign) CGSize size; 25 | @property (nonatomic, assign) BOOL isReorderable; 26 | 27 | - (instancetype)initWithSectionObject:(IGTestReorderableSectionObject *)sectionObject; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /Tests/Objects/IGTestSingleItemDataSource.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | #import <IGListKit/IGListAdapterDataSource.h> 11 | 12 | #import "IGListTestCase.h" 13 | #import "IGTestObject.h" 14 | 15 | @interface IGTestSingleItemDataSource : NSObject <IGListTestCaseDataSource> 16 | 17 | @property (nonatomic, copy) NSArray <IGTestObject *> *objects; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Tests/Objects/IGTestSingleNibItemDataSource.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | #import <IGListKit/IGListAdapterDataSource.h> 11 | 12 | #import "IGListTestCase.h" 13 | #import "IGTestObject.h" 14 | 15 | @interface IGTestSingleNibItemDataSource : NSObject <IGListTestCaseDataSource> 16 | 17 | @property (nonatomic, copy) NSArray <IGTestObject *> *objects; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Tests/Objects/IGTestSingleStoryboardItemDataSource.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <Foundation/Foundation.h> 9 | 10 | #import <IGListKit/IGListAdapterDataSource.h> 11 | 12 | #import "IGTestObject.h" 13 | 14 | @interface IGTestSingleStoryboardItemDataSource : NSObject <IGListAdapterDataSource> 15 | 16 | @property (nonatomic, copy) NSArray <IGTestObject *> *objects; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Tests/Objects/IGTestSingleWithoutDeselectionDelegate.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | 9 | #import <Foundation/Foundation.h> 10 | 11 | #import <IGListKit/IGListKit.h> 12 | 13 | @interface IGTestSingleWithoutDeselectionDelegate : NSObject <IGListSingleSectionControllerDelegate> 14 | 15 | @property (nonatomic, assign) BOOL selected; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Tests/Objects/IGTestSingleWithoutDeselectionDelegate.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | 9 | #import "IGTestSingleWithoutDeselectionDelegate.h" 10 | 11 | @implementation IGTestSingleWithoutDeselectionDelegate 12 | 13 | - (void)didSelectSectionController:(IGListSingleSectionController *)sectionController withObject:(id)object { 14 | self.selected = YES; 15 | } 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Tests/Objects/IGTestStoryboardCell.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <UIKit/UIKit.h> 9 | 10 | @interface IGTestStoryboardCell : UICollectionViewCell 11 | 12 | @property (nonatomic, weak) id delegate; 13 | @property (weak, nonatomic) IBOutlet UILabel *label; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Tests/Objects/IGTestStoryboardCell.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "IGTestStoryboardCell.h" 9 | 10 | @implementation IGTestStoryboardCell 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Tests/Objects/IGTestStoryboardSupplementarySource.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <UIKit/UIKit.h> 9 | 10 | #import <IGListKit/IGListKit.h> 11 | 12 | @interface IGTestStoryboardSupplementarySource : NSObject <IGListSupplementaryViewSource> 13 | 14 | @property (nonatomic, copy, readwrite) NSArray<NSString *> *supportedElementKinds; 15 | 16 | @property (nonatomic, weak) id<IGListCollectionContext> collectionContext; 17 | 18 | @property (nonatomic, weak) IGListSectionController *sectionController; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /Tests/Objects/IGTestStoryboardSupplementaryView.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <UIKit/UIKit.h> 9 | 10 | @interface IGTestStoryboardSupplementaryView : UICollectionReusableView 11 | 12 | @property (weak, nonatomic) IBOutlet UILabel *label; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Tests/Objects/IGTestStoryboardSupplementaryView.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "IGTestStoryboardSupplementaryView.h" 9 | 10 | @implementation IGTestStoryboardSupplementaryView 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Tests/Objects/IGTestStoryboardViewController.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <UIKit/UIKit.h> 9 | 10 | #import <IGListKit/IGListAdapterDataSource.h> 11 | 12 | #import "IGTestObject.h" 13 | 14 | @interface IGTestStoryboardViewController : UIViewController 15 | 16 | @property (weak, nonatomic) IBOutlet UICollectionView *collectionView; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Tests/Objects/IGTestStoryboardViewController.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "IGTestStoryboardViewController.h" 9 | 10 | #import "IGTestStoryboardCell.h" 11 | 12 | @interface IGTestStoryboardViewController () 13 | 14 | @end 15 | 16 | @implementation IGTestStoryboardViewController 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Tests/Objects/IGTestStringBindableCell.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <UIKit/UIKit.h> 9 | 10 | #import <IGListKit/IGListBindable.h> 11 | 12 | @interface IGTestStringBindableCell : UICollectionViewCell<IGListBindable> 13 | 14 | @property (nonatomic, strong, readonly) UILabel *label; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Tests/Objects/IGTestStringBindableCell.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "IGTestStringBindableCell.h" 9 | 10 | @implementation IGTestStringBindableCell 11 | 12 | - (instancetype)initWithFrame:(CGRect)frame { 13 | if (self = [super initWithFrame:frame]) { 14 | _label = [UILabel new]; 15 | } 16 | return self; 17 | } 18 | 19 | #pragma mark - IGListBindable 20 | 21 | - (void)bindViewModel:(id)viewModel { 22 | self.label.text = viewModel; 23 | } 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /Tests/Objects/IGTestSupplementarySource.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import <UIKit/UIKit.h> 9 | 10 | #import <IGListKit/IGListKit.h> 11 | 12 | @interface IGTestSupplementarySource : NSObject <IGListSupplementaryViewSource> 13 | 14 | @property (nonatomic, assign) BOOL dequeueFromNib; 15 | 16 | @property (nonatomic, assign) CGSize size; 17 | 18 | @property (nonatomic, copy, readwrite) NSArray<NSString *> *supportedElementKinds; 19 | 20 | @property (nonatomic, weak) id<IGListCollectionContext> collectionContext; 21 | 22 | @property (nonatomic, weak) IGListSectionController *sectionController; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /docs/badge.svg: -------------------------------------------------------------------------------- 1 | <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="20"> 2 | <linearGradient id="b" x2="0" y2="100%"> 3 | <stop offset="0" stop-color="#bbb" stop-opacity=".1"/> 4 | <stop offset="1" stop-opacity=".1"/> 5 | </linearGradient> 6 | <clipPath id="a"> 7 | <rect width="128" height="20" rx="3" fill="#fff"/> 8 | </clipPath> 9 | <g clip-path="url(#a)"> 10 | <path fill="#555" d="M0 0h93v20H0z"/> 11 | <path fill="#4c1" d="M93 0h35v20H93z"/> 12 | <path fill="url(#b)" d="M0 0h128v20H0z"/> 13 | </g> 14 | <g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110"> 15 | <text x="475" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="830"> 16 | documentation 17 | </text> 18 | <text x="475" y="140" transform="scale(.1)" textLength="830"> 19 | documentation 20 | </text> 21 | <text x="1095" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="250"> 22 | 96% 23 | </text> 24 | <text x="1095" y="140" transform="scale(.1)" textLength="250"> 25 | 96% 26 | </text> 27 | </g> 28 | </svg> 29 | -------------------------------------------------------------------------------- /docs/img/carat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Instagram/IGListKit/01bd505d8b89b55fc3938fc5ce4a9f57a7a92f81/docs/img/carat.png -------------------------------------------------------------------------------- /docs/img/dash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Instagram/IGListKit/01bd505d8b89b55fc3938fc5ce4a9f57a7a92f81/docs/img/dash.png -------------------------------------------------------------------------------- /docs/img/gh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Instagram/IGListKit/01bd505d8b89b55fc3938fc5ce4a9f57a7a92f81/docs/img/gh.png -------------------------------------------------------------------------------- /docs/img/spinner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Instagram/IGListKit/01bd505d8b89b55fc3938fc5ce4a9f57a7a92f81/docs/img/spinner.gif -------------------------------------------------------------------------------- /scripts/build_docs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright (c) Meta Platforms, Inc. and affiliates. 3 | # 4 | # This source code is licensed under the MIT license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | 7 | if ! which jazzy >/dev/null; then 8 | echo "Jazzy not detected: You can download it from https://github.com/realm/jazzy" 9 | exit 10 | fi 11 | 12 | # Docs by jazzy 13 | # https://github.com/realm/jazzy 14 | # ------------------------------ 15 | SOURCE=Source 16 | SOURCE_TMP=IGListKit 17 | SOURCEDIR=Source/ 18 | 19 | jazzy \ 20 | --objc \ 21 | --clean \ 22 | --author 'Instagram' \ 23 | --author_url 'https://twitter.com/MetaOpenSource' \ 24 | --github_url 'https://github.com/Instagram/IGListKit' \ 25 | --sdk iphonesimulator \ 26 | --module 'IGListKit' \ 27 | --framework-root $SOURCEDIR/ \ 28 | --umbrella-header $SOURCEDIR/$SOURCE_TMP/IGListKit.h \ 29 | --readme README.md \ 30 | --documentation "Guides/*.md" \ 31 | --output docs/ 32 | -------------------------------------------------------------------------------- /scripts/lint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright (c) Meta Platforms, Inc. and affiliates. 3 | # 4 | # This source code is licensed under the MIT license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | 7 | # Adds support for Apple Silicon brew directory 8 | if test -d "/opt/homebrew/bin/"; then 9 | PATH="/opt/homebrew/bin/:${PATH}" 10 | export PATH 11 | fi 12 | 13 | # Make sure bash executes from the same directory as the script 14 | cd "$(cd -P -- "$(dirname -- "$0")" && pwd -P)" 15 | 16 | VERSION="0.50.3" 17 | FOUND=$(swiftlint version) 18 | 19 | if which swiftlint >/dev/null; then 20 | swiftlint lint --config ../.swiftlint.yml 21 | else 22 | echo " 23 | Warning: SwiftLint not installed! 24 | You should download SwiftLint to verify your Swift code. 25 | Download from https://github.com/realm/SwiftLint, 26 | or brew install swiftlint. 27 | " 28 | exit 29 | fi 30 | 31 | if [ $(swiftlint version) != $VERSION ]; then 32 | echo " 33 | Warning: incorrect SwiftLint installed! 34 | Expected: $VERSION 35 | Found: $FOUND 36 | Download from https://github.com/realm/SwiftLint, 37 | or brew upgrade swiftlint. 38 | " 39 | fi 40 | 41 | exit 42 | -------------------------------------------------------------------------------- /scripts/version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright (c) Meta Platforms, Inc. and affiliates. 3 | # 4 | # This source code is licensed under the MIT license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | 7 | cd "$(dirname "$(dirname "$0")")" || exit 1 8 | 9 | exec /usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "$(pwd)/Source/Info.plist" 10 | -------------------------------------------------------------------------------- /spm/Sources/IGListDiffKit/IGListBatchUpdateData.mm: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListDiffKit/IGListBatchUpdateData.mm -------------------------------------------------------------------------------- /spm/Sources/IGListDiffKit/IGListDiff.mm: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListDiffKit/IGListDiff.mm -------------------------------------------------------------------------------- /spm/Sources/IGListDiffKit/IGListIndexPathResult.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListDiffKit/IGListIndexPathResult.m -------------------------------------------------------------------------------- /spm/Sources/IGListDiffKit/IGListIndexPathResultInternal.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListDiffKit/Internal/IGListIndexPathResultInternal.h -------------------------------------------------------------------------------- /spm/Sources/IGListDiffKit/IGListIndexSetResult.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListDiffKit/IGListIndexSetResult.m -------------------------------------------------------------------------------- /spm/Sources/IGListDiffKit/IGListIndexSetResultInternal.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListDiffKit/Internal/IGListIndexSetResultInternal.h -------------------------------------------------------------------------------- /spm/Sources/IGListDiffKit/IGListMoveIndex.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListDiffKit/IGListMoveIndex.m -------------------------------------------------------------------------------- /spm/Sources/IGListDiffKit/IGListMoveIndexInternal.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListDiffKit/Internal/IGListMoveIndexInternal.h -------------------------------------------------------------------------------- /spm/Sources/IGListDiffKit/IGListMoveIndexPath.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListDiffKit/IGListMoveIndexPath.m -------------------------------------------------------------------------------- /spm/Sources/IGListDiffKit/IGListMoveIndexPathInternal.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListDiffKit/Internal/IGListMoveIndexPathInternal.h -------------------------------------------------------------------------------- /spm/Sources/IGListDiffKit/NSNumber+IGListDiffable.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListDiffKit/NSNumber+IGListDiffable.m -------------------------------------------------------------------------------- /spm/Sources/IGListDiffKit/NSString+IGListDiffable.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListDiffKit/NSString+IGListDiffable.m -------------------------------------------------------------------------------- /spm/Sources/IGListDiffKit/include/IGListAssert.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListDiffKit/IGListAssert.h -------------------------------------------------------------------------------- /spm/Sources/IGListDiffKit/include/IGListBatchUpdateData.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListDiffKit/IGListBatchUpdateData.h -------------------------------------------------------------------------------- /spm/Sources/IGListDiffKit/include/IGListCompatibility.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListDiffKit/IGListCompatibility.h -------------------------------------------------------------------------------- /spm/Sources/IGListDiffKit/include/IGListDiff.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListDiffKit/IGListDiff.h -------------------------------------------------------------------------------- /spm/Sources/IGListDiffKit/include/IGListDiffKit.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListDiffKit/IGListDiffKit.h -------------------------------------------------------------------------------- /spm/Sources/IGListDiffKit/include/IGListDiffable.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListDiffKit/IGListDiffable.h -------------------------------------------------------------------------------- /spm/Sources/IGListDiffKit/include/IGListExperiments.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListDiffKit/IGListExperiments.h -------------------------------------------------------------------------------- /spm/Sources/IGListDiffKit/include/IGListIndexPathResult.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListDiffKit/IGListIndexPathResult.h -------------------------------------------------------------------------------- /spm/Sources/IGListDiffKit/include/IGListIndexSetResult.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListDiffKit/IGListIndexSetResult.h -------------------------------------------------------------------------------- /spm/Sources/IGListDiffKit/include/IGListMacros.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListDiffKit/IGListMacros.h -------------------------------------------------------------------------------- /spm/Sources/IGListDiffKit/include/IGListMoveIndex.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListDiffKit/IGListMoveIndex.h -------------------------------------------------------------------------------- /spm/Sources/IGListDiffKit/include/IGListMoveIndexPath.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListDiffKit/IGListMoveIndexPath.h -------------------------------------------------------------------------------- /spm/Sources/IGListDiffKit/include/NSNumber+IGListDiffable.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListDiffKit/NSNumber+IGListDiffable.h -------------------------------------------------------------------------------- /spm/Sources/IGListDiffKit/include/NSString+IGListDiffable.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListDiffKit/NSString+IGListDiffable.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListAdapter+DebugDescription.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListAdapter+DebugDescription.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListAdapter+DebugDescription.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListAdapter+DebugDescription.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListAdapter+UICollectionView.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListAdapter+UICollectionView.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListAdapter+UICollectionView.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListAdapter+UICollectionView.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListAdapter.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/IGListAdapter.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListAdapterDelegateAnnouncer.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/IGListAdapterDelegateAnnouncer.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListAdapterDelegateAnnouncerInternal.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListAdapterDelegateAnnouncerInternal.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListAdapterInternal.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListAdapterInternal.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListAdapterProxy.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListAdapterProxy.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListAdapterProxy.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListAdapterProxy.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListAdapterUpdater+DebugDescription.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListAdapterUpdater+DebugDescription.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListAdapterUpdater+DebugDescription.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListAdapterUpdater+DebugDescription.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListAdapterUpdater.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/IGListAdapterUpdater.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListAdapterUpdaterHelpers.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListAdapterUpdaterHelpers.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListAdapterUpdaterHelpers.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListAdapterUpdaterHelpers.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListAdapterUpdaterInternal.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListAdapterUpdaterInternal.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListArrayUtilsInternal.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListArrayUtilsInternal.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListArrayUtilsInternal.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListArrayUtilsInternal.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListBatchUpdateData+DebugDescription.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListBatchUpdateData+DebugDescription.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListBatchUpdateData+DebugDescription.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListBatchUpdateData+DebugDescription.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListBatchUpdateState.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListBatchUpdateState.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListBatchUpdateTransaction.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListBatchUpdateTransaction.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListBatchUpdateTransaction.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListBatchUpdateTransaction.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListBindingSectionController+DebugDescription.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListBindingSectionController+DebugDescription.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListBindingSectionController+DebugDescription.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListBindingSectionController+DebugDescription.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListBindingSectionController.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/IGListBindingSectionController.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListBindingSingleSectionController.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/IGListBindingSingleSectionController.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListCollectionView.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/IGListCollectionView.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListCollectionViewLayout.mm: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/IGListCollectionViewLayout.mm -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListCollectionViewLayoutInternal.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListCollectionViewLayoutInternal.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListCollectionViewLayoutInvalidationContext.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/IGListCollectionViewLayoutInvalidationContext.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListDataSourceChangeTransaction.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListDataSourceChangeTransaction.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListDataSourceChangeTransaction.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListDataSourceChangeTransaction.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListDebugger.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListDebugger.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListDebugger.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListDebugger.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListDebuggingUtilities.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListDebuggingUtilities.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListDebuggingUtilities.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListDebuggingUtilities.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListDefaultExperiments.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListDefaultExperiments.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListDisplayHandler.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListDisplayHandler.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListDisplayHandler.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListDisplayHandler.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListGenericSectionController.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/IGListGenericSectionController.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListIndexPathResultInternal.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListDiffKit/Internal/IGListIndexPathResultInternal.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListIndexSetResultInternal.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListDiffKit/Internal/IGListIndexSetResultInternal.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListItemUpdatesCollector.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListItemUpdatesCollector.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListItemUpdatesCollector.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListItemUpdatesCollector.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListMoveIndexInternal.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListDiffKit/Internal/IGListMoveIndexInternal.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListMoveIndexPathInternal.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListDiffKit/Internal/IGListMoveIndexPathInternal.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListPerformDiff.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListPerformDiff.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListPerformDiff.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListPerformDiff.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListReloadDataUpdater.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/IGListReloadDataUpdater.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListReloadIndexPath.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListReloadIndexPath.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListReloadIndexPath.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListReloadIndexPath.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListReloadTransaction.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListReloadTransaction.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListReloadTransaction.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListReloadTransaction.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListSectionController.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/IGListSectionController.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListSectionControllerInternal.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListSectionControllerInternal.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListSectionMap+DebugDescription.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListSectionMap+DebugDescription.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListSectionMap+DebugDescription.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListSectionMap+DebugDescription.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListSectionMap.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListSectionMap.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListSectionMap.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListSectionMap.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListSingleSectionController.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/IGListSingleSectionController.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListTransitionData.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/IGListTransitionData.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListUpdateCoalescer.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListUpdateCoalescer.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListUpdateCoalescer.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListUpdateCoalescer.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListUpdateTransactable.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListUpdateTransactable.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListUpdateTransactionBuilder.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListUpdateTransactionBuilder.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListUpdateTransactionBuilder.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListUpdateTransactionBuilder.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListViewVisibilityTracker.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListViewVisibilityTracker.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListViewVisibilityTracker.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListViewVisibilityTracker.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListViewVisibilityTrackerInternal.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListViewVisibilityTrackerInternal.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListWorkingRangeHandler.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListWorkingRangeHandler.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/IGListWorkingRangeHandler.mm: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/IGListWorkingRangeHandler.mm -------------------------------------------------------------------------------- /spm/Sources/IGListKit/UICollectionView+DebugDescription.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/UICollectionView+DebugDescription.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/UICollectionView+DebugDescription.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/UICollectionView+DebugDescription.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/UICollectionView+IGListBatchUpdateData.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/UICollectionView+IGListBatchUpdateData.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/UICollectionView+IGListBatchUpdateData.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/UICollectionView+IGListBatchUpdateData.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/UICollectionViewLayout+InteractiveReordering.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/UICollectionViewLayout+InteractiveReordering.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/UICollectionViewLayout+InteractiveReordering.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/UICollectionViewLayout+InteractiveReordering.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/UIScrollView+IGListKit.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/UIScrollView+IGListKit.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/UIScrollView+IGListKit.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/UIScrollView+IGListKit.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/UIViewController+IGListAdapter.m: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/UIViewController+IGListAdapter.m -------------------------------------------------------------------------------- /spm/Sources/IGListKit/UIViewController+IGListAdapterInternal.h: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListKit/Internal/UIViewController+IGListAdapterInternal.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/include/IGListAdapter.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListKit/IGListAdapter.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/include/IGListAdapterDataSource.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListKit/IGListAdapterDataSource.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/include/IGListAdapterDelegate.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListKit/IGListAdapterDelegate.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/include/IGListAdapterDelegateAnnouncer.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListKit/IGListAdapterDelegateAnnouncer.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/include/IGListAdapterMoveDelegate.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListKit/IGListAdapterMoveDelegate.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/include/IGListAdapterPerformanceDelegate.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListKit/IGListAdapterPerformanceDelegate.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/include/IGListAdapterUpdateListener.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListKit/IGListAdapterUpdateListener.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/include/IGListAdapterUpdater.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListKit/IGListAdapterUpdater.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/include/IGListAdapterUpdaterDelegate.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListKit/IGListAdapterUpdaterDelegate.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/include/IGListBatchContext.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListKit/IGListBatchContext.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/include/IGListBindable.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListKit/IGListBindable.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/include/IGListBindingSectionController.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListKit/IGListBindingSectionController.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/include/IGListBindingSectionControllerDataSource.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListKit/IGListBindingSectionControllerDataSource.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/include/IGListBindingSectionControllerSelectionDelegate.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListKit/IGListBindingSectionControllerSelectionDelegate.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/include/IGListBindingSingleSectionController.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListKit/IGListBindingSingleSectionController.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/include/IGListCollectionContext.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListKit/IGListCollectionContext.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/include/IGListCollectionScrollingTraits.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListKit/IGListCollectionScrollingTraits.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/include/IGListCollectionView.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListKit/IGListCollectionView.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/include/IGListCollectionViewDelegateLayout.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListKit/IGListCollectionViewDelegateLayout.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/include/IGListCollectionViewLayout.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListKit/IGListCollectionViewLayout.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/include/IGListCollectionViewLayoutCompatible.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListKit/IGListCollectionViewLayoutCompatible.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/include/IGListCollectionViewLayoutInvalidationContext.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListKit/IGListCollectionViewLayoutInvalidationContext.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/include/IGListDisplayDelegate.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListKit/IGListDisplayDelegate.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/include/IGListGenericSectionController.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListKit/IGListGenericSectionController.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/include/IGListKit.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListKit/IGListKit.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/include/IGListReloadDataUpdater.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListKit/IGListReloadDataUpdater.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/include/IGListScrollDelegate.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListKit/IGListScrollDelegate.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/include/IGListSectionController.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListKit/IGListSectionController.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/include/IGListSingleSectionController.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListKit/IGListSingleSectionController.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/include/IGListSupplementaryViewSource.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListKit/IGListSupplementaryViewSource.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/include/IGListTransitionData.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListKit/IGListTransitionData.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/include/IGListTransitionDelegate.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListKit/IGListTransitionDelegate.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/include/IGListUpdatingDelegate.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListKit/IGListUpdatingDelegate.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/include/IGListWorkingRangeDelegate.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListKit/IGListWorkingRangeDelegate.h -------------------------------------------------------------------------------- /spm/Sources/IGListKit/include/UIViewController+IGListAdapter.h: -------------------------------------------------------------------------------- 1 | ../../../../Source/IGListKit/UIViewController+IGListAdapter.h -------------------------------------------------------------------------------- /spm/Sources/IGListSwiftKit/IGListAdapter+Async.swift: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListSwiftKit/IGListAdapter+Async.swift -------------------------------------------------------------------------------- /spm/Sources/IGListSwiftKit/IGListCollectionContext+Refinements.swift: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListSwiftKit/IGListCollectionContext+Refinements.swift -------------------------------------------------------------------------------- /spm/Sources/IGListSwiftKit/IGListSingleSectionController+Refinements.swift: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListSwiftKit/IGListSingleSectionController+Refinements.swift -------------------------------------------------------------------------------- /spm/Sources/IGListSwiftKit/ListIdentifiable.swift: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListSwiftKit/ListIdentifiable.swift -------------------------------------------------------------------------------- /spm/Sources/IGListSwiftKit/ListValueSectionController.swift: -------------------------------------------------------------------------------- 1 | ../../../Source/IGListSwiftKit/ListValueSectionController.swift --------------------------------------------------------------------------------