mirror of
https://github.com/Instagram/IGListKit
synced 2026-05-24 09:48:21 +00:00
Add more unit tests to stack section controller
Summary: Beefing up our test coverage. Made an improvement to supplementary view behavior along the way. Will update `CHANGELOG.md` once travis finishes w/ link to PR #. - [x] All tests pass. Demo project builds and runs. - [x] I added tests, an experiment, or detailed why my change isn't tested. - [x] I have reviewed the [contributing guide](https://github.com/Instagram/IGListKit/blob/master/.github/CONTRIBUTING.md) Closes https://github.com/Instagram/IGListKit/pull/286 Differential Revision: D4281961 Pulled By: jessesquires fbshipit-source-id: 32b5877bd72250b9a99e600ceffc64d686fa5651
This commit is contained in:
parent
4baf267354
commit
10bdfb23f9
5 changed files with 304 additions and 42 deletions
|
|
@ -106,6 +106,10 @@ This release closes the [2.0.0 milestone](https://github.com/Instagram/IGListKit
|
|||
|
||||
- Added `tvOS` example pack. [Sherlouk](https://github.com/Sherlouk) [(#141)](https://github.com/Instagram/IGListKit/pull/141)
|
||||
|
||||
- Fixed a bug where `IGListStackSectionController` would only set its supplementary source once. [Ryan Nystrom](https://github.com/rnystrom) [(#286)](https://github.com/Instagram/IGListKit/pull/286)
|
||||
|
||||
- Fixed a bug where `IGListStackSectionController` passed the wrong section controller for will-drag scroll events. [Ryan Nystrom](https://github.com/rnystrom) [(#286)](https://github.com/Instagram/IGListKit/pull/286)
|
||||
|
||||
1.0.0
|
||||
-----
|
||||
|
||||
|
|
|
|||
|
|
@ -455,12 +455,12 @@
|
|||
8285404F1DE40D2D00118B94 /* IGListTestAdapterHorizontalDataSource.m */,
|
||||
8240C7F91DC2F6CF00B3AAE7 /* IGListTestAdapterStoryboardDataSource.h */,
|
||||
8240C7FA1DC2F6CF00B3AAE7 /* IGListTestAdapterStoryboardDataSource.m */,
|
||||
8285404A1DE40C6E00118B94 /* IGListTestHorizontalSection.h */,
|
||||
8285404B1DE40C6E00118B94 /* IGListTestHorizontalSection.m */,
|
||||
88144EF31D870EDC007C7F66 /* IGListTestOffsettingLayout.h */,
|
||||
88144EF41D870EDC007C7F66 /* IGListTestOffsettingLayout.m */,
|
||||
88144EF51D870EDC007C7F66 /* IGListTestSection.h */,
|
||||
88144EF61D870EDC007C7F66 /* IGListTestSection.m */,
|
||||
8285404A1DE40C6E00118B94 /* IGListTestHorizontalSection.h */,
|
||||
8285404B1DE40C6E00118B94 /* IGListTestHorizontalSection.m */,
|
||||
8240C7F61DC2F3FB00B3AAE7 /* IGListTestStoryboardSection.h */,
|
||||
8240C7F71DC2F3FB00B3AAE7 /* IGListTestStoryboardSection.m */,
|
||||
88144EF71D870EDC007C7F66 /* IGListTestUICollectionViewDataSource.h */,
|
||||
|
|
|
|||
|
|
@ -16,32 +16,6 @@
|
|||
|
||||
#import "IGListSectionControllerInternal.h"
|
||||
|
||||
@interface UICollectionViewCell (IGListStackedSectionController)
|
||||
@end
|
||||
@implementation UICollectionViewCell (IGListStackedSectionController)
|
||||
|
||||
static void * kStackedSectionControllerKey = &kStackedSectionControllerKey;
|
||||
|
||||
- (void)ig_setStackedSectionController:(id)stackedSectionController {
|
||||
objc_setAssociatedObject(self, kStackedSectionControllerKey, stackedSectionController, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
- (id)ig_stackedSectionController {
|
||||
return objc_getAssociatedObject(self, kStackedSectionControllerKey);
|
||||
}
|
||||
|
||||
static void * kStackedSectionControllerIndexKey = &kStackedSectionControllerIndexKey;
|
||||
|
||||
- (void)ig_setStackedSectionControllerIndex:(NSInteger)stackedSectionControllerIndex {
|
||||
objc_setAssociatedObject(self, kStackedSectionControllerIndexKey, @(stackedSectionControllerIndex), OBJC_ASSOCIATION_ASSIGN);
|
||||
}
|
||||
|
||||
- (NSInteger)ig_stackedSectionControllerIndex {
|
||||
return [objc_getAssociatedObject(self, kStackedSectionControllerIndexKey) integerValue];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation IGListStackedSectionController
|
||||
|
||||
- (instancetype)initWithSectionControllers:(NSArray <IGListSectionController<IGListSectionType> *> *)sectionControllers {
|
||||
|
|
@ -49,10 +23,6 @@ static void * kStackedSectionControllerIndexKey = &kStackedSectionControllerInde
|
|||
for (IGListSectionController<IGListSectionType> *sectionController in sectionControllers) {
|
||||
sectionController.collectionContext = self;
|
||||
sectionController.viewController = self.viewController;
|
||||
|
||||
if (self.supplementaryViewSource == nil) {
|
||||
self.supplementaryViewSource = sectionController.supplementaryViewSource;
|
||||
}
|
||||
}
|
||||
|
||||
_visibleSectionControllers = [[NSCountedSet alloc] init];
|
||||
|
|
@ -123,6 +93,15 @@ static void * kStackedSectionControllerIndexKey = &kStackedSectionControllerInde
|
|||
return itemIndexes;
|
||||
}
|
||||
|
||||
- (id<IGListSupplementaryViewSource>)supplementaryViewSource {
|
||||
for (IGListSectionController *sectionController in self.sectionControllers) {
|
||||
id<IGListSupplementaryViewSource> supplementaryViewSource = sectionController.supplementaryViewSource;
|
||||
if (supplementaryViewSource != nil) {
|
||||
return supplementaryViewSource;
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
#pragma mark - IGListSectionType
|
||||
|
||||
|
|
@ -305,9 +284,6 @@ static void * kStackedSectionControllerIndexKey = &kStackedSectionControllerInde
|
|||
IGListSectionController<IGListSectionType> *childSectionController = [self sectionControllerForObjectIndex:index];
|
||||
const NSUInteger localIndex = [self localIndexForSectionController:childSectionController index:index];
|
||||
|
||||
[cell ig_setStackedSectionController:childSectionController];
|
||||
[cell ig_setStackedSectionControllerIndex:localIndex];
|
||||
|
||||
NSCountedSet *visibleSectionControllers = self.visibleSectionControllers;
|
||||
id<IGListDisplayDelegate> displayDelegate = [childSectionController displayDelegate];
|
||||
|
||||
|
|
@ -346,7 +322,7 @@ static void * kStackedSectionControllerIndexKey = &kStackedSectionControllerInde
|
|||
|
||||
- (void)listAdapter:(IGListAdapter *)listAdapter willBeginDraggingSectionController:(IGListSectionController<IGListSectionType> *)sectionController {
|
||||
for (IGListSectionController<IGListSectionType> *childSectionController in self.sectionControllers) {
|
||||
[[childSectionController scrollDelegate] listAdapter:listAdapter willBeginDraggingSectionController:sectionController];
|
||||
[[childSectionController scrollDelegate] listAdapter:listAdapter willBeginDraggingSectionController:childSectionController];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,13 @@
|
|||
#import "IGListDisplayHandler.h"
|
||||
#import "IGListStackedSectionControllerInternal.h"
|
||||
#import "IGListTestSection.h"
|
||||
#import "IGTestCell.h"
|
||||
#import "IGTestStackedDataSource.h"
|
||||
#import "IGTestStoryboardCell.h"
|
||||
#import "IGTestStoryboardViewController.h"
|
||||
#import "IGTestSupplementarySource.h"
|
||||
#import "IGTestSupplementarySource.h"
|
||||
#import "IGTestStoryboardSupplementarySource.h"
|
||||
|
||||
static const CGRect kStackTestFrame = (CGRect){{0.0, 0.0}, {100.0, 100.0}};
|
||||
|
||||
|
|
@ -37,9 +43,15 @@ static const CGRect kStackTestFrame = (CGRect){{0.0, 0.0}, {100.0, 100.0}};
|
|||
|
||||
self.window = [[UIWindow alloc] initWithFrame:kStackTestFrame];
|
||||
|
||||
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
|
||||
self.collectionView = [[IGListCollectionView alloc] initWithFrame:kStackTestFrame collectionViewLayout:layout];
|
||||
[self.window addSubview:self.collectionView];
|
||||
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"IGTestStoryboard" bundle:[NSBundle bundleForClass:self.class]];
|
||||
IGTestStoryboardViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"testVC"];
|
||||
self.window.rootViewController = vc;
|
||||
[self.window addSubview:vc.view];
|
||||
[vc performSelectorOnMainThread:@selector(loadView) withObject:nil waitUntilDone:YES];
|
||||
self.collectionView = vc.collectionView;
|
||||
|
||||
vc.view.frame = kStackTestFrame;
|
||||
self.collectionView.frame = kStackTestFrame;
|
||||
|
||||
self.dataSource = [[IGTestStackedDataSource alloc] init];
|
||||
self.adapter = [[IGListAdapter alloc] initWithUpdater:[IGListAdapterUpdater new] viewController:nil workingRangeSize:0];
|
||||
|
|
@ -431,4 +443,247 @@ static const CGRect kStackTestFrame = (CGRect){{0.0, 0.0}, {100.0, 100.0}};
|
|||
[self waitForExpectationsWithTimeout:15 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_whenSelectingItems_thatChildSectionControllersSelected {
|
||||
[self setupWithObjects:@[
|
||||
[[IGTestObject alloc] initWithKey:@0 value:@[@1, @2, @3]],
|
||||
[[IGTestObject alloc] initWithKey:@1 value:@[@1, @2, @3]],
|
||||
[[IGTestObject alloc] initWithKey:@2 value:@[@1, @1]]
|
||||
]];
|
||||
|
||||
[self.adapter collectionView:self.collectionView didSelectItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]];
|
||||
[self.adapter collectionView:self.collectionView didSelectItemAtIndexPath:[NSIndexPath indexPathForItem:2 inSection:1]];
|
||||
[self.adapter collectionView:self.collectionView didSelectItemAtIndexPath:[NSIndexPath indexPathForItem:1 inSection:2]];
|
||||
|
||||
IGListStackedSectionController *stack0 = [self.adapter sectionControllerForObject:self.dataSource.objects[0]];
|
||||
IGListStackedSectionController *stack1 = [self.adapter sectionControllerForObject:self.dataSource.objects[1]];
|
||||
IGListStackedSectionController *stack2 = [self.adapter sectionControllerForObject:self.dataSource.objects[2]];
|
||||
|
||||
XCTAssertTrue([stack0.sectionControllers[0] wasSelected]);
|
||||
XCTAssertFalse([stack0.sectionControllers[1] wasSelected]);
|
||||
XCTAssertFalse([stack0.sectionControllers[2] wasSelected]);
|
||||
XCTAssertFalse([stack1.sectionControllers[0] wasSelected]);
|
||||
XCTAssertTrue([stack1.sectionControllers[1] wasSelected]);
|
||||
XCTAssertFalse([stack1.sectionControllers[2] wasSelected]);
|
||||
XCTAssertFalse([stack2.sectionControllers[0] wasSelected]);
|
||||
XCTAssertTrue([stack2.sectionControllers[1] wasSelected]);
|
||||
}
|
||||
|
||||
- (void)test_whenUsingNibs_withStoryboards_thatCellsAreConfigured {
|
||||
[self setupWithObjects:@[
|
||||
[[IGTestObject alloc] initWithKey:@0 value:@[@1, @"nib", @"storyboard"]],
|
||||
]];
|
||||
|
||||
UICollectionViewCell *cell0 = [self.collectionView cellForItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]];
|
||||
IGTestCell *cell1 = (IGTestCell *)[self.collectionView cellForItemAtIndexPath:[NSIndexPath indexPathForItem:1 inSection:0]];
|
||||
IGTestStoryboardCell *cell2 = (IGTestStoryboardCell *)[self.collectionView cellForItemAtIndexPath:[NSIndexPath indexPathForItem:2 inSection:0]];
|
||||
|
||||
XCTAssertEqualObjects(cell0.class, [UICollectionViewCell class]);
|
||||
XCTAssertEqualObjects(cell1.class, [IGTestCell class]);
|
||||
XCTAssertEqualObjects(cell2.class, [IGTestStoryboardCell class]);
|
||||
|
||||
XCTAssertEqualObjects(cell1.label.text, @"nib");
|
||||
XCTAssertEqualObjects(cell2.label.text, @"storyboard");
|
||||
}
|
||||
|
||||
- (void)test_whenForwardingDidScrollEvent_thatChildSectionControllersReceiveEvent {
|
||||
[self setupWithObjects:@[
|
||||
[[IGTestObject alloc] initWithKey:@0 value:@[@1, @2, @3]],
|
||||
[[IGTestObject alloc] initWithKey:@2 value:@[@1, @1]]
|
||||
]];
|
||||
|
||||
id mockScrollDelegate = [OCMockObject mockForProtocol:@protocol(IGListScrollDelegate)];
|
||||
|
||||
IGListStackedSectionController *stack0 = [self.adapter sectionControllerForObject:self.dataSource.objects[0]];
|
||||
IGListStackedSectionController *stack1 = [self.adapter sectionControllerForObject:self.dataSource.objects[1]];
|
||||
|
||||
[stack0.sectionControllers[0] setScrollDelegate:mockScrollDelegate];
|
||||
[stack0.sectionControllers[1] setScrollDelegate:mockScrollDelegate];
|
||||
[stack0.sectionControllers[2] setScrollDelegate:mockScrollDelegate];
|
||||
[stack1.sectionControllers[0] setScrollDelegate:mockScrollDelegate];
|
||||
[stack1.sectionControllers[1] setScrollDelegate:mockScrollDelegate];
|
||||
|
||||
[[mockScrollDelegate expect] listAdapter:self.adapter didScrollSectionController:stack0.sectionControllers[0]];
|
||||
[[mockScrollDelegate expect] listAdapter:self.adapter didScrollSectionController:stack0.sectionControllers[1]];
|
||||
[[mockScrollDelegate expect] listAdapter:self.adapter didScrollSectionController:stack0.sectionControllers[2]];
|
||||
[[mockScrollDelegate expect] listAdapter:self.adapter didScrollSectionController:stack1.sectionControllers[0]];
|
||||
[[mockScrollDelegate expect] listAdapter:self.adapter didScrollSectionController:stack1.sectionControllers[1]];
|
||||
|
||||
[self.adapter scrollViewDidScroll:self.collectionView];
|
||||
|
||||
[mockScrollDelegate verify];
|
||||
}
|
||||
|
||||
- (void)test_whenForwardingWillBeginDraggingEvent_thatChildSectionControllersReceiveEvent {
|
||||
[self setupWithObjects:@[
|
||||
[[IGTestObject alloc] initWithKey:@0 value:@[@1, @2, @3]],
|
||||
[[IGTestObject alloc] initWithKey:@2 value:@[@1, @1]]
|
||||
]];
|
||||
|
||||
id mockScrollDelegate = [OCMockObject mockForProtocol:@protocol(IGListScrollDelegate)];
|
||||
|
||||
IGListStackedSectionController *stack0 = [self.adapter sectionControllerForObject:self.dataSource.objects[0]];
|
||||
IGListStackedSectionController *stack1 = [self.adapter sectionControllerForObject:self.dataSource.objects[1]];
|
||||
|
||||
[stack0.sectionControllers[0] setScrollDelegate:mockScrollDelegate];
|
||||
[stack0.sectionControllers[1] setScrollDelegate:mockScrollDelegate];
|
||||
[stack0.sectionControllers[2] setScrollDelegate:mockScrollDelegate];
|
||||
[stack1.sectionControllers[0] setScrollDelegate:mockScrollDelegate];
|
||||
[stack1.sectionControllers[1] setScrollDelegate:mockScrollDelegate];
|
||||
|
||||
[[mockScrollDelegate expect] listAdapter:self.adapter willBeginDraggingSectionController:stack0.sectionControllers[0]];
|
||||
[[mockScrollDelegate expect] listAdapter:self.adapter willBeginDraggingSectionController:stack0.sectionControllers[1]];
|
||||
[[mockScrollDelegate expect] listAdapter:self.adapter willBeginDraggingSectionController:stack0.sectionControllers[2]];
|
||||
[[mockScrollDelegate expect] listAdapter:self.adapter willBeginDraggingSectionController:stack1.sectionControllers[0]];
|
||||
[[mockScrollDelegate expect] listAdapter:self.adapter willBeginDraggingSectionController:stack1.sectionControllers[1]];
|
||||
|
||||
[self.adapter scrollViewWillBeginDragging:self.collectionView];
|
||||
|
||||
[mockScrollDelegate verify];
|
||||
}
|
||||
|
||||
- (void)test_whenForwardingDidEndDraggingEvent_thatChildSectionControllersReceiveEvent {
|
||||
[self setupWithObjects:@[
|
||||
[[IGTestObject alloc] initWithKey:@0 value:@[@1, @2, @3]],
|
||||
[[IGTestObject alloc] initWithKey:@2 value:@[@1, @1]]
|
||||
]];
|
||||
|
||||
id mockScrollDelegate = [OCMockObject mockForProtocol:@protocol(IGListScrollDelegate)];
|
||||
|
||||
IGListStackedSectionController *stack0 = [self.adapter sectionControllerForObject:self.dataSource.objects[0]];
|
||||
IGListStackedSectionController *stack1 = [self.adapter sectionControllerForObject:self.dataSource.objects[1]];
|
||||
|
||||
[stack0.sectionControllers[0] setScrollDelegate:mockScrollDelegate];
|
||||
[stack0.sectionControllers[1] setScrollDelegate:mockScrollDelegate];
|
||||
[stack0.sectionControllers[2] setScrollDelegate:mockScrollDelegate];
|
||||
[stack1.sectionControllers[0] setScrollDelegate:mockScrollDelegate];
|
||||
[stack1.sectionControllers[1] setScrollDelegate:mockScrollDelegate];
|
||||
|
||||
[[mockScrollDelegate expect] listAdapter:self.adapter didEndDraggingSectionController:stack0.sectionControllers[0] willDecelerate:NO];
|
||||
[[mockScrollDelegate expect] listAdapter:self.adapter didEndDraggingSectionController:stack0.sectionControllers[1] willDecelerate:NO];
|
||||
[[mockScrollDelegate expect] listAdapter:self.adapter didEndDraggingSectionController:stack0.sectionControllers[2] willDecelerate:NO];
|
||||
[[mockScrollDelegate expect] listAdapter:self.adapter didEndDraggingSectionController:stack1.sectionControllers[0] willDecelerate:NO];
|
||||
[[mockScrollDelegate expect] listAdapter:self.adapter didEndDraggingSectionController:stack1.sectionControllers[1] willDecelerate:NO];
|
||||
|
||||
[self.adapter scrollViewDidEndDragging:self.collectionView willDecelerate:NO];
|
||||
|
||||
[mockScrollDelegate verify];
|
||||
}
|
||||
|
||||
- (void)test_whenUsingSupplementary_withCode_thatSupplementaryViewExists {
|
||||
// updater that uses reloadData so we can rebuild all views/sizes
|
||||
IGListAdapter *adapter = [[IGListAdapter alloc] initWithUpdater:[IGListReloadDataUpdater new] viewController:nil workingRangeSize:0];
|
||||
|
||||
self.dataSource.objects = @[
|
||||
[[IGTestObject alloc] initWithKey:@0 value:@[@1, @2, @3]],
|
||||
[[IGTestObject alloc] initWithKey:@2 value:@[@1, @1]]
|
||||
];
|
||||
|
||||
adapter.collectionView = self.collectionView;
|
||||
adapter.dataSource = self.dataSource;
|
||||
[self.collectionView layoutIfNeeded];
|
||||
|
||||
IGListStackedSectionController *stack = [adapter sectionControllerForObject:self.dataSource.objects[1]];
|
||||
IGListTestSection *section = stack.sectionControllers.lastObject;
|
||||
|
||||
IGTestSupplementarySource *supplementarySource = [IGTestSupplementarySource new];
|
||||
// the stack acts as the collection context. manually assign it.
|
||||
supplementarySource.collectionContext = stack;
|
||||
// however the actual section controller the supplementary serves is a child of the stack
|
||||
supplementarySource.sectionController = section;
|
||||
supplementarySource.supportedElementKinds = @[UICollectionElementKindSectionFooter];
|
||||
|
||||
section.supplementaryViewSource = supplementarySource;
|
||||
|
||||
[adapter performUpdatesAnimated:NO completion:nil];
|
||||
|
||||
XCTAssertNotNil([self.collectionView supplementaryViewForElementKind:UICollectionElementKindSectionFooter
|
||||
atIndexPath:[NSIndexPath indexPathForItem:0 inSection:1]]);
|
||||
XCTAssertNotNil(supplementarySource);
|
||||
}
|
||||
|
||||
- (void)test_whenUsingSupplementary_withNib_thatSupplementaryViewExists {
|
||||
// updater that uses reloadData so we can rebuild all views/sizes
|
||||
IGListAdapter *adapter = [[IGListAdapter alloc] initWithUpdater:[IGListReloadDataUpdater new] viewController:nil workingRangeSize:0];
|
||||
|
||||
self.dataSource.objects = @[
|
||||
[[IGTestObject alloc] initWithKey:@0 value:@[@1, @2, @3]],
|
||||
[[IGTestObject alloc] initWithKey:@2 value:@[@1, @1]]
|
||||
];
|
||||
|
||||
adapter.collectionView = self.collectionView;
|
||||
adapter.dataSource = self.dataSource;
|
||||
[self.collectionView layoutIfNeeded];
|
||||
|
||||
IGListStackedSectionController *stack = [adapter sectionControllerForObject:self.dataSource.objects[1]];
|
||||
IGListTestSection *section = stack.sectionControllers.lastObject;
|
||||
|
||||
IGTestSupplementarySource *supplementarySource = [IGTestSupplementarySource new];
|
||||
// the stack acts as the collection context. manually assign it.
|
||||
supplementarySource.collectionContext = stack;
|
||||
// however the actual section controller the supplementary serves is a child of the stack
|
||||
supplementarySource.sectionController = section;
|
||||
supplementarySource.supportedElementKinds = @[UICollectionElementKindSectionFooter];
|
||||
supplementarySource.dequeueFromNib = YES;
|
||||
|
||||
section.supplementaryViewSource = supplementarySource;
|
||||
|
||||
[adapter performUpdatesAnimated:NO completion:nil];
|
||||
|
||||
XCTAssertNotNil([self.collectionView supplementaryViewForElementKind:UICollectionElementKindSectionFooter
|
||||
atIndexPath:[NSIndexPath indexPathForItem:0 inSection:1]]);
|
||||
XCTAssertNotNil(supplementarySource);
|
||||
}
|
||||
|
||||
- (void)test_whenUsingSupplementary_withStoryboard_thatSupplementaryViewExists {
|
||||
// updater that uses reloadData so we can rebuild all views/sizes
|
||||
IGListAdapter *adapter = [[IGListAdapter alloc] initWithUpdater:[IGListReloadDataUpdater new] viewController:nil workingRangeSize:0];
|
||||
|
||||
self.dataSource.objects = @[
|
||||
[[IGTestObject alloc] initWithKey:@0 value:@[@1, @2, @3]],
|
||||
[[IGTestObject alloc] initWithKey:@2 value:@[@1, @1]]
|
||||
];
|
||||
|
||||
adapter.collectionView = self.collectionView;
|
||||
adapter.dataSource = self.dataSource;
|
||||
[self.collectionView layoutIfNeeded];
|
||||
|
||||
IGListStackedSectionController *stack = [adapter sectionControllerForObject:self.dataSource.objects[1]];
|
||||
IGListTestSection *section = stack.sectionControllers.lastObject;
|
||||
|
||||
IGTestStoryboardSupplementarySource *supplementarySource = [IGTestStoryboardSupplementarySource new];
|
||||
// the stack acts as the collection context. manually assign it.
|
||||
supplementarySource.collectionContext = stack;
|
||||
// however the actual section controller the supplementary serves is a child of the stack
|
||||
supplementarySource.sectionController = section;
|
||||
|
||||
// the "section header" property of the parent collection view must be checked
|
||||
supplementarySource.supportedElementKinds = @[UICollectionElementKindSectionHeader];
|
||||
|
||||
section.supplementaryViewSource = supplementarySource;
|
||||
|
||||
[adapter performUpdatesAnimated:NO completion:nil];
|
||||
|
||||
XCTAssertNotNil([self.collectionView supplementaryViewForElementKind:UICollectionElementKindSectionHeader
|
||||
atIndexPath:[NSIndexPath indexPathForItem:0 inSection:1]]);
|
||||
XCTAssertNotNil(supplementarySource);
|
||||
}
|
||||
|
||||
- (void)test_whenScrollingFromChildSectionController_thatScrollsToCorrectPosition {
|
||||
// pad with enough items that we can freely scroll to the middle without accounting for content size
|
||||
[self setupWithObjects:@[
|
||||
[[IGTestObject alloc] initWithKey:@0 value:@[@4, @5, @6]],
|
||||
[[IGTestObject alloc] initWithKey:@1 value:@[@1, @2, @3]],
|
||||
[[IGTestObject alloc] initWithKey:@2 value:@[@4, @5, @6]]
|
||||
]];
|
||||
|
||||
IGListStackedSectionController *stack = [self.adapter sectionControllerForObject:self.dataSource.objects[1]];
|
||||
IGListTestSection *section = stack.sectionControllers[1];
|
||||
|
||||
[section.collectionContext scrollToSectionController:section atIndex:1 scrollPosition:UICollectionViewScrollPositionTop animated:NO];
|
||||
|
||||
// IGListTestSection cells are 100x10
|
||||
XCTAssertEqual(self.collectionView.contentOffset.x, 0);
|
||||
XCTAssertEqual(self.collectionView.contentOffset.y, 170);
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#import <IGListKit/IGListStackedSectionController.h>
|
||||
|
||||
#import "IGTestCell.h"
|
||||
#import "IGListTestSection.h"
|
||||
|
||||
@implementation IGTestStackedDataSource
|
||||
|
|
@ -21,9 +22,35 @@
|
|||
|
||||
- (IGListSectionController <IGListSectionType> *)listAdapter:(IGListAdapter *)listAdapter sectionControllerForObject:(id)object {
|
||||
NSMutableArray *controllers = [[NSMutableArray alloc] init];
|
||||
for (NSNumber *num in [(IGTestObject *)object value]) {
|
||||
IGListTestSection *controller = [[IGListTestSection alloc] init];
|
||||
controller.items = [num integerValue];
|
||||
for (id value in [(IGTestObject *)object value]) {
|
||||
id controller;
|
||||
// use a standard IGListTestSection
|
||||
if ([value isKindOfClass:[NSNumber class]]) {
|
||||
IGListTestSection *section = [[IGListTestSection alloc] init];
|
||||
section.items = [value integerValue];
|
||||
controller = section;
|
||||
} else if ([value isKindOfClass:[NSString class]]) {
|
||||
void (^configureBlock)(id, __kindof UICollectionViewCell *) = ^(id obj, IGTestCell *cell) {
|
||||
// capturing the value in block scope so we use the CHILD OBJECT of the stack
|
||||
// otherwise the block uses the IGTestObject in the block param
|
||||
cell.label.text = value;
|
||||
};
|
||||
CGSize (^sizeBlock)(id, id<IGListCollectionContext>) = ^CGSize(IGTestObject *item, id<IGListCollectionContext> collectionContext) {
|
||||
return CGSizeMake([collectionContext containerSize].width, 44);
|
||||
};
|
||||
|
||||
// use either nibs or storyboards with NSString depending on the string value
|
||||
if ([value isEqualToString:@"nib"]) {
|
||||
controller = [[IGListSingleSectionController alloc] initWithNibName:@"IGTestNibCell"
|
||||
bundle:[NSBundle bundleForClass:self.class]
|
||||
configureBlock:configureBlock
|
||||
sizeBlock:sizeBlock];
|
||||
} else {
|
||||
controller = [[IGListSingleSectionController alloc] initWithStoryboardCellIdentifier:@"IGTestStoryboardCell"
|
||||
configureBlock:configureBlock
|
||||
sizeBlock:sizeBlock];
|
||||
}
|
||||
}
|
||||
[controllers addObject:controller];
|
||||
}
|
||||
return [[IGListStackedSectionController alloc] initWithSectionControllers:controllers];
|
||||
|
|
|
|||
Loading…
Reference in a new issue