Skip to content

Commit

Permalink
Prevent negative spaces for items and supplementaries
Browse files Browse the repository at this point in the history
Summary:
If a negative height/width comes down, cap it to `0.0`.

Issue fixed: Instagram#566

Also fixes t16455632 internally.

- [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 added an entry to the `CHANGELOG.md` for any breaking changes, enhancements, or bug fixes.
Closes Instagram#583

Differential Revision: D4797520

Pulled By: jessesquires

fbshipit-source-id: 3eeec5244a445bb451460286b4f006ca0d9c67d1
  • Loading branch information
Ryan Nystrom authored and facebook-github-bot committed Mar 29, 2017
1 parent a98c4ff commit 4e9b0bb
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 15 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ This release closes the [3.0.0 milestone](https://github.com/Instagram/IGListKit
- Fix a potential crash when a section is moved and deleted at the same time. [Ryan Nystrom](https://github.com/rnystrom) [(#577)](https://github.com/Instagram/IGListKit/pull/577)
- Prevent section controllers and supplementary sources from returning negative sizes that crash `UICollectionViewFlowLayout`. [Ryan Nystrom](https://github.com/rnystrom) [(#583)](https://github.com/Instagram/IGListKit/pull/583)
2.1.0
-----
Expand Down
6 changes: 4 additions & 2 deletions Source/IGListAdapter.m
Original file line number Diff line number Diff line change
Expand Up @@ -458,14 +458,16 @@ - (CGSize)sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
IGAssertMainThread();

IGListSectionController <IGListSectionType> *sectionController = [self sectionControllerForSection:indexPath.section];
return [sectionController sizeForItemAtIndex:indexPath.item];
const CGSize size = [sectionController sizeForItemAtIndex:indexPath.item];
return CGSizeMake(MAX(size.width, 0.0), MAX(size.height, 0.0));
}

- (CGSize)sizeForSupplementaryViewOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath {
IGAssertMainThread();
id <IGListSupplementaryViewSource> supplementaryViewSource = [self supplementaryViewSourceAtIndexPath:indexPath];
if ([[supplementaryViewSource supportedElementKinds] containsObject:elementKind]) {
return [supplementaryViewSource sizeForSupplementaryViewOfKind:elementKind atIndex:indexPath.item];
const CGSize size = [supplementaryViewSource sizeForSupplementaryViewOfKind:elementKind atIndex:indexPath.item];
return CGSizeMake(MAX(size.width, 0.0), MAX(size.height, 0.0));
}
return CGSizeZero;
}
Expand Down
28 changes: 28 additions & 0 deletions Tests/IGListAdapterTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -1083,4 +1083,32 @@ - (void)test_whenSectionEdgeInsetIsNotZero {
IGAssertEqualSize([self.adapter containerSizeForSectionController:controller], 98, 98);
}

- (void)test_whenSectionControllerReturnsNegativeSize_thatAdapterReturnsZero {
self.dataSource.objects = @[@1];
IGListTestSection *section = [self.adapter sectionControllerForObject:self.dataSource.objects[0]];
section.size = CGSizeMake(-1, -1);
const CGSize size = [self.adapter sizeForItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]];
XCTAssertEqual(size.width, 0.0);
XCTAssertEqual(size.height, 0.0);
}

- (void)test_whenSupplementarySourceReturnsNegativeSize_thatAdapterReturnsZero {
self.dataSource.objects = @[@1];
[self.adapter reloadDataWithCompletion:nil];

IGTestSupplementarySource *supplementarySource = [IGTestSupplementarySource new];
supplementarySource.collectionContext = self.adapter;
supplementarySource.supportedElementKinds = @[UICollectionElementKindSectionFooter];
supplementarySource.size = CGSizeMake(-1, -1);

IGListSectionController<IGListSectionType> *controller = [self.adapter sectionControllerForObject:@1];
controller.supplementaryViewSource = supplementarySource;
supplementarySource.sectionController = controller;

const CGSize size = [self.adapter sizeForSupplementaryViewOfKind:UICollectionElementKindSectionHeader
atIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]];
XCTAssertEqual(size.width, 0.0);
XCTAssertEqual(size.height, 0.0);
}

@end
2 changes: 2 additions & 0 deletions Tests/Objects/IGListTestSection.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

@property (nonatomic, assign) NSInteger items;

@property (nonatomic, assign) CGSize size;

@property (nonatomic, assign) BOOL wasSelected;

@end
9 changes: 8 additions & 1 deletion Tests/Objects/IGListTestSection.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@

@implementation IGListTestSection

- (instancetype)init {
if (self = [super init]) {
_size = CGSizeMake(100, 10);
}
return self;
}

- (NSArray <Class> *)cellClasses {
return @[UICollectionViewCell.class];
}
Expand All @@ -20,7 +27,7 @@ - (NSInteger)numberOfItems {
}

- (CGSize)sizeForItemAtIndex:(NSInteger)index {
return CGSizeMake(100, 10);
return self.size;
}

- (UICollectionViewCell *)cellForItemAtIndex:(NSInteger)index {
Expand Down
6 changes: 0 additions & 6 deletions Tests/Objects/IGTestStoryboardSupplementarySource.m
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,4 @@ - (CGSize)sizeForSupplementaryViewOfKind:(NSString *)elementKind atIndex:(NSInte
return CGSizeMake([self.collectionContext containerSize].width, 45);
}

- (CGSize)estimatedSizeForSupplementaryViewOfKind:(NSString *)elementKind
atIndex:(NSInteger)index {
return CGSizeZero;
}


@end
2 changes: 2 additions & 0 deletions Tests/Objects/IGTestSupplementarySource.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

@property (nonatomic, assign) BOOL dequeueFromNib;

@property (nonatomic, assign) CGSize size;

@property (nonatomic, strong, readwrite) NSArray<NSString *> *supportedElementKinds;

@property (nonatomic, weak) id<IGListCollectionContext> collectionContext;
Expand Down
14 changes: 8 additions & 6 deletions Tests/Objects/IGTestSupplementarySource.m
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@

@implementation IGTestSupplementarySource

- (instancetype)init {
if (self = [super init]) {
_size = CGSizeMake(100, 10);
}
return self;
}

#pragma mark - IGListSupplementaryViewSource

- (UICollectionReusableView *)viewForSupplementaryElementOfKind:(NSString *)elementKind
Expand All @@ -34,12 +41,7 @@ - (UICollectionReusableView *)viewForSupplementaryElementOfKind:(NSString *)elem
}

- (CGSize)sizeForSupplementaryViewOfKind:(NSString *)elementKind atIndex:(NSInteger)index {
return CGSizeMake([self.collectionContext containerSize].width, 10);
}

- (CGSize)estimatedSizeForSupplementaryViewOfKind:(NSString *)elementKind
atIndex:(NSInteger)index {
return CGSizeZero;
return self.size;
}

@end

0 comments on commit 4e9b0bb

Please sign in to comment.