mirror of
https://github.com/Instagram/IGListKit
synced 2026-05-23 09:18:29 +00:00
Container Inset Size For Section Controller
Summary: Add API for #315. Not sure if this is what you want rnystrom though 🤔. Will add tests after you confirm. - [x] All tests pass. Demo project builds and runs. - [x] I added tests, an experiment, or detailed why my change isn't tested. - [ ] I added an entry to the `CHANGELOG.md` for any breaking changes, enhancements, or bug fixes. - [x] I have reviewed the [contributing guide](https://github.com/Instagram/IGListKit/blob/master/.github/CONTRIBUTING.md) Closes https://github.com/Instagram/IGListKit/pull/456 Reviewed By: jessesquires Differential Revision: D4697190 Pulled By: rnystrom fbshipit-source-id: f8513cf2fa33441eb40f486954136553d19dda0c
This commit is contained in:
parent
79348164a7
commit
f7702fa713
10 changed files with 142 additions and 3 deletions
|
|
@ -236,6 +236,8 @@
|
|||
8285404D1DE40C6E00118B94 /* IGListTestHorizontalSection.m in Sources */ = {isa = PBXBuildFile; fileRef = 8285404B1DE40C6E00118B94 /* IGListTestHorizontalSection.m */; };
|
||||
828540501DE40D2D00118B94 /* IGListTestAdapterHorizontalDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 8285404F1DE40D2D00118B94 /* IGListTestAdapterHorizontalDataSource.m */; };
|
||||
828540511DE40D2D00118B94 /* IGListTestAdapterHorizontalDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 8285404F1DE40D2D00118B94 /* IGListTestAdapterHorizontalDataSource.m */; };
|
||||
82914C5B1E6E2DEC0066C2F8 /* IGListTestContainerSizeSection.m in Sources */ = {isa = PBXBuildFile; fileRef = 82914C5A1E6E2DEC0066C2F8 /* IGListTestContainerSizeSection.m */; };
|
||||
82914C5C1E6E2DEC0066C2F8 /* IGListTestContainerSizeSection.m in Sources */ = {isa = PBXBuildFile; fileRef = 82914C5A1E6E2DEC0066C2F8 /* IGListTestContainerSizeSection.m */; };
|
||||
829D7BAA1DD1819000549816 /* IGListSectionMapTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 829D7BA81DD1816400549816 /* IGListSectionMapTests.m */; };
|
||||
88144F071D870EDC007C7F66 /* IGListAdapterE2ETests.m in Sources */ = {isa = PBXBuildFile; fileRef = 88144EE21D870EDC007C7F66 /* IGListAdapterE2ETests.m */; };
|
||||
88144F081D870EDC007C7F66 /* IGListAdapterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 88144EE31D870EDC007C7F66 /* IGListAdapterTests.m */; };
|
||||
|
|
@ -451,6 +453,8 @@
|
|||
8285404B1DE40C6E00118B94 /* IGListTestHorizontalSection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGListTestHorizontalSection.m; sourceTree = "<group>"; };
|
||||
8285404E1DE40D2D00118B94 /* IGListTestAdapterHorizontalDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IGListTestAdapterHorizontalDataSource.h; sourceTree = "<group>"; };
|
||||
8285404F1DE40D2D00118B94 /* IGListTestAdapterHorizontalDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGListTestAdapterHorizontalDataSource.m; sourceTree = "<group>"; };
|
||||
82914C591E6E2DEC0066C2F8 /* IGListTestContainerSizeSection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IGListTestContainerSizeSection.h; sourceTree = "<group>"; };
|
||||
82914C5A1E6E2DEC0066C2F8 /* IGListTestContainerSizeSection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGListTestContainerSizeSection.m; sourceTree = "<group>"; };
|
||||
829D7BA81DD1816400549816 /* IGListSectionMapTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGListSectionMapTests.m; sourceTree = "<group>"; };
|
||||
841726B542A3E9A4BD48946F /* Pods-IGListKit-tvOSTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-IGListKit-tvOSTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-IGListKit-tvOSTests/Pods-IGListKit-tvOSTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
88144EE21D870EDC007C7F66 /* IGListAdapterE2ETests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGListAdapterE2ETests.m; sourceTree = "<group>"; };
|
||||
|
|
@ -739,6 +743,8 @@
|
|||
298DD9D91E3ADE3300F76F50 /* IGTestStringBindableCell.m */,
|
||||
88144F051D870EDC007C7F66 /* IGTestSupplementarySource.h */,
|
||||
88144F061D870EDC007C7F66 /* IGTestSupplementarySource.m */,
|
||||
82914C591E6E2DEC0066C2F8 /* IGListTestContainerSizeSection.h */,
|
||||
82914C5A1E6E2DEC0066C2F8 /* IGListTestContainerSizeSection.m */,
|
||||
);
|
||||
path = Objects;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -1344,6 +1350,7 @@
|
|||
298DDA3C1E3B170300F76F50 /* IGLayoutTestSection.m in Sources */,
|
||||
298DDA0A1E3AE31E00F76F50 /* IGTestDiffingSectionController.m in Sources */,
|
||||
29C4748D1DDF45F900AE68CE /* IGListAdapterProxyTests.m in Sources */,
|
||||
82914C5C1E6E2DEC0066C2F8 /* IGListTestContainerSizeSection.m in Sources */,
|
||||
885FE22C1DC51B76009CE2B4 /* IGListAdapterTests.m in Sources */,
|
||||
298DDA051E3AE2B000F76F50 /* IGTestStringBindableCell.m in Sources */,
|
||||
885FE22D1DC51B76009CE2B4 /* IGListAdapterUpdaterTests.m in Sources */,
|
||||
|
|
@ -1431,6 +1438,7 @@
|
|||
298DDA3D1E3B170400F76F50 /* IGLayoutTestSection.m in Sources */,
|
||||
298DDA091E3AE31D00F76F50 /* IGTestDiffingSectionController.m in Sources */,
|
||||
88144F151D870EDC007C7F66 /* IGListTestSection.m in Sources */,
|
||||
82914C5B1E6E2DEC0066C2F8 /* IGListTestContainerSizeSection.m in Sources */,
|
||||
88144F1D1D870EDC007C7F66 /* IGTestSupplementarySource.m in Sources */,
|
||||
298DDA071E3AE2B100F76F50 /* IGTestStringBindableCell.m in Sources */,
|
||||
88144F081D870EDC007C7F66 /* IGListAdapterTests.m in Sources */,
|
||||
|
|
|
|||
|
|
@ -818,6 +818,12 @@
|
|||
return UIEdgeInsetsInsetRect(self.collectionView.bounds, self.collectionView.contentInset).size;
|
||||
}
|
||||
|
||||
- (CGSize)containerSizeForSectionController:(IGListSectionController<IGListSectionType> *)sectionController {
|
||||
const UIEdgeInsets inset = sectionController.inset;
|
||||
return CGSizeMake(self.containerSize.width - inset.left - inset.right,
|
||||
self.containerSize.height - inset.top - inset.bottom);
|
||||
}
|
||||
|
||||
- (NSInteger)indexForCell:(UICollectionViewCell *)cell sectionController:(nonnull IGListSectionController<IGListSectionType> *)sectionController {
|
||||
IGAssertMainThread();
|
||||
IGParameterAssert(cell != nil);
|
||||
|
|
|
|||
|
|
@ -25,6 +25,15 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
*/
|
||||
@property (nonatomic, readonly) CGSize containerSize;
|
||||
|
||||
/**
|
||||
Returns size of the collection view relative to the section controller.
|
||||
|
||||
@param sectionController The section controller requesting this information.
|
||||
|
||||
@return The size of the collection view minus the given section controller's insets.
|
||||
*/
|
||||
- (CGSize)containerSizeForSectionController:(IGListSectionController<IGListSectionType> *)sectionController;
|
||||
|
||||
/**
|
||||
Returns the index of the specified cell in the collection relative to the section controller.
|
||||
|
||||
|
|
|
|||
|
|
@ -165,6 +165,12 @@ static void * kStackedSectionControllerIndexKey = &kStackedSectionControllerInde
|
|||
return [self.collectionContext containerSize];
|
||||
}
|
||||
|
||||
- (CGSize)containerSizeForSectionController:(IGListSectionController<IGListSectionType> *)sectionController {
|
||||
const UIEdgeInsets inset = sectionController.inset;
|
||||
return CGSizeMake(self.containerSize.width - inset.left - inset.right,
|
||||
self.containerSize.height - inset.top - inset.bottom);
|
||||
}
|
||||
|
||||
- (NSInteger)indexForCell:(UICollectionViewCell *)cell sectionController:(IGListSectionController<IGListSectionType> *)sectionController {
|
||||
const NSInteger index = [self.collectionContext indexForCell:cell sectionController:self];
|
||||
return [self localIndexForSectionController:sectionController index:index];
|
||||
|
|
|
|||
|
|
@ -27,6 +27,12 @@ CGPoint p = CGPointMake(x, y); \
|
|||
XCTAssertEqual(CGPointEqualToPoint(point, p), YES); \
|
||||
} while(0)
|
||||
|
||||
#define IGAssertEqualSize(size, w, h, ...) \
|
||||
do { \
|
||||
CGSize s = CGSizeMake(w, h); \
|
||||
XCTAssertEqual(CGSizeEqualToSize(size, s), YES); \
|
||||
} while(0)
|
||||
|
||||
@interface IGListAdapterTests : XCTestCase
|
||||
|
||||
// infra does not hold a strong ref to collection view
|
||||
|
|
@ -1083,4 +1089,12 @@ XCTAssertEqual(CGPointEqualToPoint(point, p), YES); \
|
|||
XCTAssertEqualObjects(self.adapter.objects, expected);
|
||||
}
|
||||
|
||||
- (void)test_whenSectionEdgeInsetIsNotZero {
|
||||
// IGListTestAdapterDataSource does not handle NSStrings
|
||||
self.dataSource.objects = @[@42];
|
||||
[self.adapter reloadDataWithCompletion:nil];
|
||||
IGListSectionController<IGListSectionType> *controller = [self.adapter sectionControllerForObject:@42];
|
||||
IGAssertEqualSize([self.adapter containerSizeForSectionController:controller], 98, 98);
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#import "IGListDisplayHandler.h"
|
||||
#import "IGListStackedSectionControllerInternal.h"
|
||||
#import "IGListTestSection.h"
|
||||
#import "IGListTestContainerSizeSection.h"
|
||||
#import "IGTestCell.h"
|
||||
#import "IGTestStackedDataSource.h"
|
||||
#import "IGTestStoryboardCell.h"
|
||||
|
|
@ -25,6 +26,12 @@
|
|||
#import "IGTestSupplementarySource.h"
|
||||
#import "IGTestStoryboardSupplementarySource.h"
|
||||
|
||||
#define IGAssertEqualSize(size, w, h, ...) \
|
||||
do { \
|
||||
CGSize s = CGSizeMake(w, h); \
|
||||
XCTAssertEqual(CGSizeEqualToSize(size, s), YES); \
|
||||
} while(0)
|
||||
|
||||
static const CGRect kStackTestFrame = (CGRect){{0.0, 0.0}, {100.0, 100.0}};
|
||||
|
||||
@interface IGListStackSectionControllerTests : XCTestCase
|
||||
|
|
@ -142,6 +149,15 @@ static const CGRect kStackTestFrame = (CGRect){{0.0, 0.0}, {100.0, 100.0}};
|
|||
XCTAssertTrue(CGSizeEqualToSize([section1.collectionContext containerSize], kStackTestFrame.size));
|
||||
}
|
||||
|
||||
- (void)test_whenSectionEdgeInsetIsNotZero {
|
||||
[self setupWithObjects:@[
|
||||
[[IGTestObject alloc] initWithKey:@0 value:@[@42]]
|
||||
]];
|
||||
IGListStackedSectionController *stack = [self.adapter sectionControllerForObject:self.dataSource.objects[0]];
|
||||
IGListTestContainerSizeSection *section1 = stack.sectionControllers[0];
|
||||
IGAssertEqualSize([stack containerSizeForSectionController:section1], 98, 98);
|
||||
}
|
||||
|
||||
- (void)test_whenQueryingCellIndex_thatIndexIsRelativeToSectionController {
|
||||
[self setupWithObjects:@[
|
||||
[[IGTestObject alloc] initWithKey:@0 value:@[@1, @1, @2]]
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#import <IGListKit/IGListAdapter.h>
|
||||
|
||||
#import "IGListTestSection.h"
|
||||
#import "IGListTestContainerSizeSection.h"
|
||||
|
||||
@implementation IGListTestAdapterDataSource
|
||||
|
||||
|
|
@ -21,6 +22,9 @@
|
|||
|
||||
- (IGListSectionController <IGListSectionType> *)listAdapter:(IGListAdapter *)listAdapter sectionControllerForObject:(id)object {
|
||||
if ([object isKindOfClass:[NSNumber class]]) {
|
||||
if ([(NSNumber*)object isEqual: @42]) {
|
||||
return [IGListTestContainerSizeSection new];
|
||||
}
|
||||
return [IGListTestSection new];
|
||||
}
|
||||
return nil;
|
||||
|
|
|
|||
19
Tests/Objects/IGListTestContainerSizeSection.h
Normal file
19
Tests/Objects/IGListTestContainerSizeSection.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/**
|
||||
* Copyright (c) 2016-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <IGListKit/IGListSectionController.h>
|
||||
#import <IGListKit/IGListSectionType.h>
|
||||
|
||||
@interface IGListTestContainerSizeSection : IGListSectionController <IGListSectionType>
|
||||
|
||||
@property (nonatomic, assign) NSInteger items;
|
||||
|
||||
@end
|
||||
50
Tests/Objects/IGListTestContainerSizeSection.m
Normal file
50
Tests/Objects/IGListTestContainerSizeSection.m
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* Copyright (c) 2016-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#import "IGListTestContainerSizeSection.h"
|
||||
|
||||
@implementation IGListTestContainerSizeSection
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
self.inset = UIEdgeInsetsMake(1.0, 1.0, 1.0, 1.0);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSArray <Class> *)cellClasses {
|
||||
return @[UICollectionViewCell.class];
|
||||
}
|
||||
|
||||
- (NSInteger)numberOfItems {
|
||||
return self.items;
|
||||
}
|
||||
|
||||
- (CGSize)sizeForItemAtIndex:(NSInteger)index {
|
||||
return CGSizeMake(100, 10);
|
||||
}
|
||||
|
||||
- (UICollectionViewCell *)cellForItemAtIndex:(NSInteger)index {
|
||||
return [self.collectionContext dequeueReusableCellOfClass:UICollectionViewCell.class
|
||||
forSectionController:self
|
||||
atIndex:index];
|
||||
}
|
||||
|
||||
- (void)didUpdateToObject:(id)object {
|
||||
if ([object isKindOfClass:[NSNumber class]]) {
|
||||
self.items = [object integerValue];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)didSelectItemAtIndex:(NSInteger)index {
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#import "IGTestCell.h"
|
||||
#import "IGListTestSection.h"
|
||||
#import "IGListTestContainerSizeSection.h"
|
||||
|
||||
@implementation IGTestStackedDataSource
|
||||
|
||||
|
|
@ -26,9 +27,15 @@
|
|||
id controller;
|
||||
// use a standard IGListTestSection
|
||||
if ([value isKindOfClass:[NSNumber class]]) {
|
||||
IGListTestSection *section = [[IGListTestSection alloc] init];
|
||||
section.items = [value integerValue];
|
||||
controller = section;
|
||||
if ([(NSNumber*)value isEqual: @42]) {
|
||||
IGListTestContainerSizeSection *section = [[IGListTestContainerSizeSection alloc] init];
|
||||
section.items = [value integerValue];
|
||||
controller = section;
|
||||
} else {
|
||||
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
|
||||
|
|
|
|||
Loading…
Reference in a new issue