Container size doesnt use content inset, add new APIs

Summary:
The content inset of a collection view can change at any time (as it does with our refresh control) and isn't a good measure of the container size. I don't want to totally remove that API though, so I changed the default behavior, added an insets API, and also added the functionality of the original in a new API.

This makes sizes much more deterministic.

Reviewed By: jessesquires

Differential Revision: D4800758

fbshipit-source-id: 85ce843b5b1c297cea2e2ea705fa255617cbe356
This commit is contained in:
Ryan Nystrom 2017-03-30 09:23:32 -07:00 committed by Facebook Github Bot
parent 4e9b0bb4c4
commit 623ff2a8a8
7 changed files with 101 additions and 2 deletions

View file

@ -52,6 +52,8 @@ This release closes the [3.0.0 milestone](https://github.com/Instagram/IGListKit
} completion:nil];
```
- `-[IGListCollectionContext containerSize]` no longer accounts for the content inset of the collection view when returning a size. If you require that behavior, you can now use `-[IGListCollectionContext insetContainerSize]`. [Ryan Nystrom](https://github.com/rnystrom) (tbd)
### Enhancements

View file

@ -15,6 +15,10 @@
#import "ImageSectionController.h"
#import "PhotoCell.h"
@interface ImageSectionController () <IGListSupplementaryViewSource>
@end
@implementation ImageSectionController
#pragma mark - IGListSectionType
@ -39,4 +43,22 @@
}
- (id<IGListSupplementaryViewSource>)supplementaryViewSource {
return self;
}
- (NSArray<NSString *> *)supportedElementKinds {
return @[UICollectionElementKindSectionFooter];
}
- (CGSize)sizeForSupplementaryViewOfKind:(NSString *)elementKind atIndex:(NSInteger)index {
return CGSizeMake(self.collectionContext.containerSize.width, 30);
}
- (UICollectionReusableView *)viewForSupplementaryElementOfKind:(NSString *)elementKind atIndex:(NSInteger)index {
UICollectionReusableView *view = [self.collectionContext dequeueReusableSupplementaryViewOfKind:elementKind forSectionController:self class:[UICollectionReusableView class] atIndex:index];
view.backgroundColor = [UIColor yellowColor];
return view;
}
@end

View file

@ -817,7 +817,16 @@
#pragma mark - IGListCollectionContext
- (CGSize)containerSize {
return UIEdgeInsetsInsetRect(self.collectionView.bounds, self.collectionView.contentInset).size;
return self.collectionView.bounds.size;
}
- (UIEdgeInsets)containerInset {
return self.collectionView.contentInset;
}
- (CGSize)insetContainerSize {
IGListCollectionView *collectionView = self.collectionView;
return UIEdgeInsetsInsetRect(collectionView.bounds, collectionView.contentInset).size;
}
- (CGSize)containerSizeForSectionController:(IGListSectionController<IGListSectionType> *)sectionController {

View file

@ -24,10 +24,20 @@ NS_ASSUME_NONNULL_BEGIN
@protocol IGListCollectionContext <NSObject>
/**
The size of the collection view. You may use this for sizing cells.
The size of the collection view. You can use this for sizing cells.
*/
@property (nonatomic, readonly) CGSize containerSize;
/**
The content insets of the collection view. You can use this for sizing cells.
*/
@property (nonatomic, readonly) UIEdgeInsets containerInset;
/**
The size of the collection view with content insets applied.
*/
@property (nonatomic, readonly) CGSize insetContainerSize;
/**
Returns size of the collection view relative to the section controller.

View file

@ -165,6 +165,14 @@ static void * kStackedSectionControllerIndexKey = &kStackedSectionControllerInde
return [self.collectionContext containerSize];
}
- (UIEdgeInsets)containerInset {
return [self.collectionContext containerInset];
}
- (CGSize)insetContainerSize {
return [self.collectionContext insetContainerSize];
}
- (CGSize)containerSizeForSectionController:(IGListSectionController<IGListSectionType> *)sectionController {
const UIEdgeInsets inset = sectionController.inset;
return CGSizeMake(self.containerSize.width - inset.left - inset.right,

View file

@ -1111,4 +1111,26 @@ XCTAssertEqual(CGSizeEqualToSize(size, s), YES); \
XCTAssertEqual(size.height, 0.0);
}
- (void)test_whenQueryingContainerInset_thatMatchesCollectionView {
self.dataSource.objects = @[@2];
[self.adapter reloadDataWithCompletion:nil];
self.collectionView.contentInset = UIEdgeInsetsMake(1, 2, 3, 4);
IGListSectionController<IGListSectionType> *controller = [self.adapter sectionControllerForObject:@2];
const UIEdgeInsets inset = [controller.collectionContext containerInset];
XCTAssertEqual(inset.top, 1);
XCTAssertEqual(inset.left, 2);
XCTAssertEqual(inset.bottom, 3);
XCTAssertEqual(inset.right, 4);
}
- (void)test_whenQueryingInsetContainerSize_thatResultIsBoundsInsetByContent {
self.dataSource.objects = @[@2];
[self.adapter reloadDataWithCompletion:nil];
self.collectionView.contentInset = UIEdgeInsetsMake(1, 2, 3, 4);
IGListSectionController<IGListSectionType> *controller = [self.adapter sectionControllerForObject:@2];
const CGSize size = [controller.collectionContext insetContainerSize];
XCTAssertEqual(size.width, 94);
XCTAssertEqual(size.height, 96);
}
@end

View file

@ -158,6 +158,32 @@ static const CGRect kStackTestFrame = (CGRect){{0.0, 0.0}, {100.0, 100.0}};
IGAssertEqualSize([stack containerSizeForSectionController:section1], 98, 98);
}
- (void)test_whenQueryingContainerInset_thatMatchesCollectionView {
self.collectionView.contentInset = UIEdgeInsetsMake(1, 2, 3, 4);
[self setupWithObjects:@[
[[IGTestObject alloc] initWithKey:@0 value:@[@42]]
]];
IGListStackedSectionController *stack = [self.adapter sectionControllerForObject:self.dataSource.objects[0]];
IGListTestContainerSizeSection *section1 = stack.sectionControllers[0];
const UIEdgeInsets inset = [section1.collectionContext containerInset];
XCTAssertEqual(inset.top, 1);
XCTAssertEqual(inset.left, 2);
XCTAssertEqual(inset.bottom, 3);
XCTAssertEqual(inset.right, 4);
}
- (void)test_whenQueryingInsetContainerSize_thatBoundsInsetByContent {
self.collectionView.contentInset = UIEdgeInsetsMake(1, 2, 3, 4);
[self setupWithObjects:@[
[[IGTestObject alloc] initWithKey:@0 value:@[@42]]
]];
IGListStackedSectionController *stack = [self.adapter sectionControllerForObject:self.dataSource.objects[0]];
IGListTestContainerSizeSection *section1 = stack.sectionControllers[0];
const CGSize size = [section1.collectionContext insetContainerSize];
XCTAssertEqual(size.width, 94);
XCTAssertEqual(size.height, 96);
}
- (void)test_whenQueryingCellIndex_thatIndexIsRelativeToSectionController {
[self setupWithObjects:@[
[[IGTestObject alloc] initWithKey:@0 value:@[@1, @1, @2]]