update iglistkit (#1354)

This commit is contained in:
Ryan Nystrom
2018-01-06 11:55:09 -05:00
committed by GitHub
parent ae4adaab28
commit 819b7952f1
21 changed files with 936 additions and 620 deletions

View File

@@ -24,6 +24,8 @@ typedef NS_OPTIONS (NSInteger, IGListExperiment) {
IGListExperimentReloadDataFallback = 1 << 3,
/// Test a faster way to return visible section controllers.
IGListExperimentFasterVisibleSectionController = 1 << 4,
/// Test deduping item-level updates.
IGListExperimentDedupeItemUpdates = 1 << 5,
};
/**

View File

@@ -16,6 +16,7 @@
#import "IGListSectionControllerInternal.h"
#import "IGListDebugger.h"
#import "IGListArrayUtilsInternal.h"
#import "UIScrollView+IGListKit.h"
@implementation IGListAdapter {
NSMapTable<UICollectionReusableView *, IGListSectionController *> *_viewSectionControllerMap;
@@ -102,7 +103,7 @@
_collectionView = collectionView;
_collectionView.dataSource = self;
if ([_collectionView respondsToSelector:@selector(setPrefetchingEnabled:)]) {
if (@available(iOS 10.0, tvOS 10, *)) {
_collectionView.prefetchingEnabled = NO;
}
@@ -249,7 +250,7 @@
const CGFloat offsetMid = (offsetMin + offsetMax) / 2.0;
const CGFloat collectionViewWidth = collectionView.bounds.size.width;
const CGFloat collectionViewHeight = collectionView.bounds.size.height;
const UIEdgeInsets contentInset = collectionView.contentInset;
const UIEdgeInsets contentInset = collectionView.ig_contentInset;
CGPoint contentOffset = collectionView.contentOffset;
switch (scrollDirection) {
case UICollectionViewScrollDirectionHorizontal: {
@@ -270,8 +271,8 @@
contentOffset.x = offsetMin - contentInset.left;
break;
}
const CGFloat maxOffsetX = collectionView.contentSize.width - collectionView.frame.size.width + collectionView.contentInset.right;
const CGFloat minOffsetX = -collectionView.contentInset.left;
const CGFloat maxOffsetX = collectionView.contentSize.width - collectionView.frame.size.width + contentInset.right;
const CGFloat minOffsetX = -contentInset.left;
contentOffset.x = MIN(contentOffset.x, maxOffsetX);
contentOffset.x = MAX(contentOffset.x, minOffsetX);
break;
@@ -294,8 +295,8 @@
contentOffset.y = offsetMin - contentInset.top;
break;
}
const CGFloat maxOffsetY = collectionView.contentSize.height - collectionView.frame.size.height + collectionView.contentInset.bottom;
const CGFloat minOffsetY = -collectionView.contentInset.top;
const CGFloat maxOffsetY = collectionView.contentSize.height - collectionView.frame.size.height + contentInset.bottom;
const CGFloat minOffsetY = -contentInset.top;
contentOffset.y = MIN(contentOffset.y, maxOffsetY);
contentOffset.y = MAX(contentOffset.y, minOffsetY);
break;
@@ -830,9 +831,13 @@
return self.collectionView.contentInset;
}
- (UIEdgeInsets)adjustedContainerInset {
return self.collectionView.ig_contentInset;
}
- (CGSize)insetContainerSize {
UICollectionView *collectionView = self.collectionView;
return UIEdgeInsetsInsetRect(collectionView.bounds, collectionView.contentInset).size;
return UIEdgeInsetsInsetRect(collectionView.bounds, collectionView.ig_contentInset).size;
}
- (CGSize)containerSizeForSectionController:(IGListSectionController *)sectionController {

View File

@@ -309,6 +309,11 @@ void convertReloadToDeleteInsert(NSMutableIndexSet *reloads,
[itemDeletes addObjectsFromArray:[reloadDeletePaths allObjects]];
[itemInserts addObjectsFromArray:[reloadInsertPaths allObjects]];
if (IGListExperimentEnabled(self.experiments, IGListExperimentDedupeItemUpdates)) {
itemDeletes = [[[NSSet setWithArray:itemDeletes] allObjects] mutableCopy];
itemInserts = [[[NSSet setWithArray:itemInserts] allObjects] mutableCopy];
}
IGListBatchUpdateData *updateData = [[IGListBatchUpdateData alloc] initWithInsertSections:inserts
deleteSections:deletes
moveSections:moves

View File

@@ -32,6 +32,11 @@ NS_SWIFT_NAME(ListCollectionContext)
*/
@property (nonatomic, readonly) UIEdgeInsets containerInset;
/**
The adjusted content insets of the collection view. Equivalent to containerInset under iOS 11.
*/
@property (nonatomic, readonly) UIEdgeInsets adjustedContainerInset;
/**
The size of the collection view with content insets applied.
*/

View File

@@ -0,0 +1,46 @@
/**
* 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>
@class IGListCollectionViewLayout;
NS_ASSUME_NONNULL_BEGIN
/**
This `UICollectionView` subclass allows for partial layout invalidation using `IGListCollectionViewLayout`.
@note When updating a collection view (ex: calling `-insertSections`), `-invalidateLayoutWithContext` gets called on
the layout object. However, the invalidation context doesn't provide details on which index paths are being modified,
which typically forces a full layout re-calculation. `IGListCollectionView` gives `IGListCollectionViewLayout` the
missing information to re-calculate only the modified layout attributes.
*/
NS_SWIFT_NAME(ListCollectionView)
@interface IGListCollectionView : UICollectionView
/**
Create a new view with an `IGListcollectionViewLayout` class or subclass.
@param frame The frame to initialize with.
@param collectionViewLayout The layout to use with the collection view.
@note You can initialize a new view with a base layout by simply calling `-[IGListCollectionView initWithFrame:]`.
*/
- (instancetype)initWithFrame:(CGRect)frame listCollectionViewLayout:(IGListCollectionViewLayout *)collectionViewLayout NS_DESIGNATED_INITIALIZER;
/**
:nodoc:
*/
- (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)collectionViewLayout NS_UNAVAILABLE;
- (instancetype)initWithCoder:(NSCoder *)aDecoder NS_UNAVAILABLE;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,106 @@
/**
* 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 "IGListCollectionView.h"
#import "IGListCollectionViewLayout.h"
@implementation IGListCollectionView
#pragma mark - Init
- (instancetype)initWithFrame:(CGRect)frame {
IGListCollectionViewLayout *layout = [[IGListCollectionViewLayout alloc] initWithStickyHeaders:NO topContentInset:0 stretchToEdge:YES];
return [self initWithFrame:frame listCollectionViewLayout:layout];
}
- (instancetype)initWithFrame:(CGRect)frame listCollectionViewLayout:(IGListCollectionViewLayout *)collectionViewLayout {
return [super initWithFrame:frame collectionViewLayout:collectionViewLayout];
}
#pragma mark - IGListCollectionViewLayout
- (IGListCollectionViewLayout *)listLayout {
if ([self.collectionViewLayout isKindOfClass:[IGListCollectionViewLayout class]]) {
return (IGListCollectionViewLayout *)self.collectionViewLayout;
}
return nil;
}
#pragma mark - Overides reloads
- (void)reloadItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths {
[self didModifyIndexPaths:indexPaths];
[super reloadItemsAtIndexPaths:indexPaths];
}
- (void)reloadSections:(NSIndexSet *)sections {
[self didModifySections:sections];
[super reloadSections:sections];
}
#pragma mark - Override deletes
- (void)deleteItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths {
[self didModifyIndexPaths:indexPaths];
[super deleteItemsAtIndexPaths:indexPaths];
}
- (void)deleteSections:(NSIndexSet *)sections {
[self didModifySections:sections];
[super deleteSections:sections];
}
#pragma mark - Override inserts
- (void)insertItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths {
[self didModifyIndexPaths:indexPaths];
[super insertItemsAtIndexPaths:indexPaths];
}
- (void)insertSections:(NSIndexSet *)sections {
[self didModifySections:sections];
[super insertSections:sections];
}
#pragma mark - Override moves
- (void)moveItemAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath {
[self didModifyIndexPaths:@[indexPath, newIndexPath]];
[super moveItemAtIndexPath:indexPath toIndexPath:newIndexPath];
}
- (void)moveSection:(NSInteger)section toSection:(NSInteger)newSection {
[self didModifySection:MIN(section, newSection)];
[super moveSection:section toSection:newSection];
}
#pragma mark - Modify section
- (void)didModifySections:(NSIndexSet *)sections {
if (sections.count == 0) {
return;
}
[self didModifySection:sections.firstIndex];
}
- (void)didModifySection:(NSUInteger)section {
[self.listLayout didModifySection:section];
}
#pragma mark - Modified index path
- (void)didModifyIndexPaths:(NSArray<NSIndexPath *> *)indexPaths {
for (NSIndexPath *indexPath in indexPaths) {
[self didModifySection:indexPath.section];
}
}
@end

View File

@@ -88,6 +88,17 @@ NS_SWIFT_NAME(ListCollectionViewLayout)
*/
@property (nonatomic, assign) CGFloat stickyHeaderYOffset;
/**
Notify the layout that a specific section was modified before invalidation. Used to optimize layout re-calculation.
@note When updating a collection view (ex: calling `-insertSections`), `-invalidateLayoutWithContext` gets called on
the layout object. However, the invalidation context doesn't provide details on which index paths are being modified,
which typically forces a full layout re-calculation. We can use this method to keep track of which section actually
needs to be updated on the following `-invalidateLayoutWithContext`. See `IGListCollectionView`.
@param modifiedSection The section that was modified.
*/
- (void)didModifySection:(NSInteger)modifiedSection;
/**
Create and return a new collection view layout.

View File

@@ -9,6 +9,7 @@
#import "IGListCollectionViewLayout.h"
#import "IGListCollectionViewLayoutInternal.h"
#import "UIScrollView+IGListKit.h"
#import <vector>
@@ -67,6 +68,18 @@ static NSIndexPath *indexPathForSection(NSInteger section) {
return [NSIndexPath indexPathForItem:0 inSection:section];
}
static NSInteger IGListMergeMinimumInvalidatedSection(NSInteger section, NSInteger otherSection) {
if (section == NSNotFound && otherSection == NSNotFound) {
return NSNotFound;
} else if (section == NSNotFound) {
return otherSection;
} else if (otherSection == NSNotFound) {
return section;
}
return MIN(section, otherSection);
}
struct IGListSectionEntry {
/**
Represents the minimum-bounding box of every element in the section. This includes all item frames as well as the
@@ -87,6 +100,15 @@ struct IGListSectionEntry {
// An array of frames for each cell in the section.
std::vector<CGRect> itemBounds;
// last item distance in scroll direction, used for partial invalidation
CGFloat lastItemCoordInScrollDirection;
// last item distance in fixed direction, used for partial invalidation
CGFloat lastItemCoordInFixedDirection;
// last next row distance in scroll direction, used for partial invalidation
CGFloat lastNextRowCoordInScrollDirection;
// Returns YES when the section has visible content (header and/or items).
BOOL isValid() {
return !CGSizeEqualToSize(bounds.size, CGSizeZero);
@@ -133,7 +155,9 @@ static void adjustZIndexForAttributes(UICollectionViewLayoutAttributes *attribut
@implementation IGListCollectionViewLayout {
std::vector<IGListSectionEntry> _sectionData;
NSMutableDictionary<NSIndexPath *, UICollectionViewLayoutAttributes *> *_attributesCache;
BOOL _cachedLayoutInvalid;
// invalidate starting at this section
NSInteger _minimumInvalidatedSection;
/**
The workflow for getting sticky headers working:
@@ -171,7 +195,7 @@ static void adjustZIndexForAttributes(UICollectionViewLayoutAttributes *attribut
UICollectionElementKindSectionHeader: [NSMutableDictionary new],
UICollectionElementKindSectionFooter: [NSMutableDictionary new],
}];
_cachedLayoutInvalid = YES;
_minimumInvalidatedSection = NSNotFound;
}
return self;
}
@@ -312,8 +336,7 @@ static void adjustZIndexForAttributes(UICollectionViewLayoutAttributes *attribut
const IGListSectionEntry section = _sectionData[sectionCount - 1];
UICollectionView *collectionView = self.collectionView;
const UIEdgeInsets contentInset = collectionView.contentInset;
const UIEdgeInsets contentInset = collectionView.ig_contentInset;
switch (self.scrollDirection) {
case UICollectionViewScrollDirectionVertical: {
const CGFloat height = CGRectGetMaxY(section.bounds) + section.insets.bottom;
@@ -335,9 +358,12 @@ static void adjustZIndexForAttributes(UICollectionViewLayoutAttributes *attribut
if (hasInvalidatedItemIndexPaths
|| [context invalidateEverything]
|| [context invalidateDataSourceCounts]
|| context.ig_invalidateAllAttributes) {
_cachedLayoutInvalid = YES;
// invalidates all
_minimumInvalidatedSection = 0;
} else if ([context invalidateDataSourceCounts] && _minimumInvalidatedSection == NSNotFound) {
// invalidate all if count changed and we don't have information on the minimum invalidated section
_minimumInvalidatedSection = 0;
}
if (context.ig_invalidateSupplementaryAttributes) {
@@ -376,9 +402,7 @@ static void adjustZIndexForAttributes(UICollectionViewLayoutAttributes *attribut
}
- (void)prepareLayout {
if (_cachedLayoutInvalid) {
[self cacheLayout];
}
[self calculateLayoutIfNeeded];
}
#pragma mark - Public API
@@ -397,8 +421,10 @@ static void adjustZIndexForAttributes(UICollectionViewLayoutAttributes *attribut
#pragma mark - Private API
- (void)cacheLayout {
_cachedLayoutInvalid = NO;
- (void)calculateLayoutIfNeeded {
if (_minimumInvalidatedSection == NSNotFound) {
return;
}
// purge attribute caches so they are rebuilt
[_attributesCache removeAllObjects];
@@ -409,10 +435,10 @@ static void adjustZIndexForAttributes(UICollectionViewLayoutAttributes *attribut
id<UICollectionViewDelegateFlowLayout> delegate = (id<UICollectionViewDelegateFlowLayout>)collectionView.delegate;
const NSInteger sectionCount = [dataSource numberOfSectionsInCollectionView:collectionView];
const UIEdgeInsets contentInset = collectionView.contentInset;
const UIEdgeInsets contentInset = collectionView.ig_contentInset;
const CGRect contentInsetAdjustedCollectionViewBounds = UIEdgeInsetsInsetRect(collectionView.bounds, contentInset);
auto sectionData = std::vector<IGListSectionEntry>(sectionCount);
_sectionData.resize(sectionCount);
CGFloat itemCoordInScrollDirection = 0.0;
CGFloat itemCoordInFixedDirection = 0.0;
@@ -421,9 +447,18 @@ static void adjustZIndexForAttributes(UICollectionViewLayoutAttributes *attribut
// union item frames and optionally the header to find a bounding box of the entire section
CGRect rollingSectionBounds;
for (NSInteger section = 0; section < sectionCount; section++) {
// populate last valid section information
const NSInteger lastValidSection = _minimumInvalidatedSection - 1;
if (lastValidSection >= 0 && lastValidSection < sectionCount) {
itemCoordInScrollDirection = _sectionData[lastValidSection].lastItemCoordInScrollDirection;
itemCoordInFixedDirection = _sectionData[lastValidSection].lastItemCoordInFixedDirection;
nextRowCoordInScrollDirection = _sectionData[lastValidSection].lastNextRowCoordInScrollDirection;
rollingSectionBounds = _sectionData[lastValidSection].bounds;
}
for (NSInteger section = _minimumInvalidatedSection; section < sectionCount; section++) {
const NSInteger itemCount = [dataSource collectionView:collectionView numberOfItemsInSection:section];
sectionData[section].itemBounds = std::vector<CGRect>(itemCount);
_sectionData[section].itemBounds = std::vector<CGRect>(itemCount);
const CGSize headerSize = [delegate collectionView:collectionView layout:self referenceSizeForHeaderInSection:section];
const CGSize footerSize = [delegate collectionView:collectionView layout:self referenceSizeForFooterInSection:section];
@@ -498,7 +533,7 @@ static void adjustZIndexForAttributes(UICollectionViewLayoutAttributes *attribut
itemLengthInFixedDirection);
const CGRect frame = IGListRectIntegralScaled(rawFrame);
sectionData[section].itemBounds[item] = frame;
_sectionData[section].itemBounds[item] = frame;
// track the max size of the row to find the coord of the next row, adjust for leading inset while iterating items
nextRowCoordInScrollDirection = MAX(CGRectGetMaxInDirection(frame, self.scrollDirection) - UIEdgeInsetsLeadingInsetInDirection(insets, self.scrollDirection), nextRowCoordInScrollDirection);
@@ -524,7 +559,7 @@ static void adjustZIndexForAttributes(UICollectionViewLayoutAttributes *attribut
headerSize.width,
paddedLengthInFixedDirection);
sectionData[section].headerBounds = headerBounds;
_sectionData[section].headerBounds = headerBounds;
const CGRect footerBounds = (self.scrollDirection == UICollectionViewScrollDirectionVertical) ?
CGRectMake(insets.left,
@@ -536,7 +571,7 @@ static void adjustZIndexForAttributes(UICollectionViewLayoutAttributes *attribut
footerSize.width,
paddedLengthInFixedDirection);
sectionData[section].footerBounds = footerBounds;
_sectionData[section].footerBounds = footerBounds;
// union the header before setting the bounds of the section
// only do this when the header has a size, otherwise the union stretches to box empty space
@@ -547,17 +582,22 @@ static void adjustZIndexForAttributes(UICollectionViewLayoutAttributes *attribut
rollingSectionBounds = CGRectUnion(rollingSectionBounds, footerBounds);
}
sectionData[section].bounds = rollingSectionBounds;
sectionData[section].insets = insets;
_sectionData[section].bounds = rollingSectionBounds;
_sectionData[section].insets = insets;
// bump the coord for the next section with the right insets
itemCoordInFixedDirection += UIEdgeInsetsTrailingInsetInDirection(insets, fixedDirection);
// find the farthest point in the section and add the trailing inset to find the next row's coord
nextRowCoordInScrollDirection = MAX(nextRowCoordInScrollDirection, CGRectGetMaxInDirection(rollingSectionBounds, self.scrollDirection) + UIEdgeInsetsTrailingInsetInDirection(insets, self.scrollDirection));
// keep track of coordinates for partial invalidation
_sectionData[section].lastItemCoordInScrollDirection = itemCoordInScrollDirection;
_sectionData[section].lastItemCoordInFixedDirection = itemCoordInFixedDirection;
_sectionData[section].lastNextRowCoordInScrollDirection = nextRowCoordInScrollDirection;
}
_sectionData = sectionData;
_minimumInvalidatedSection = NSNotFound;
}
- (NSRange)rangeOfSectionsInRect:(CGRect)rect {
@@ -585,4 +625,10 @@ static void adjustZIndexForAttributes(UICollectionViewLayoutAttributes *attribut
}];
}
#pragma mark - Minimum Invalidated Section
- (void)didModifySection:(NSInteger)modifiedSection {
_minimumInvalidatedSection = IGListMergeMinimumInvalidatedSection(_minimumInvalidatedSection, modifiedSection);
}
@end

View File

@@ -36,6 +36,7 @@ FOUNDATION_EXPORT const unsigned char IGListKitVersionString[];
#import <IGListKit/IGListBindingSectionControllerDataSource.h>
#import <IGListKit/IGListBindingSectionControllerSelectionDelegate.h>
#import <IGListKit/IGListCollectionContext.h>
#import <IGListKit/IGListCollectionView.h>
#import <IGListKit/IGListCollectionViewLayout.h>
#import <IGListKit/IGListDisplayDelegate.h>
#import <IGListKit/IGListExperiments.h>

View File

@@ -53,6 +53,18 @@ NS_SWIFT_NAME(ListSingleSectionControllerDelegate)
- (void)didSelectSectionController:(IGListSingleSectionController *)sectionController
withObject:(id)object;
/**
Tells the delegate that the section controller was deselected.
@param sectionController The section controller that was deselected.
@param object The model for the given section.
@note Method is `@optional` until the 4.0.0 release where it will become required.
*/
@optional
- (void)didDeselectSectionController:(IGListSingleSectionController *)sectionController
withObject:(id)object;
@end
/**

View File

@@ -109,4 +109,10 @@
[self.selectionDelegate didSelectSectionController:self withObject:self.item];
}
- (void)didDeselectItemAtIndex:(NSInteger)index {
if ([self.selectionDelegate respondsToSelector:@selector(didDeselectSectionController:withObject:)]) {
[self.selectionDelegate didDeselectSectionController:self withObject:self.item];
}
}
@end

View File

@@ -188,6 +188,10 @@ static void * kStackedSectionControllerIndexKey = &kStackedSectionControllerInde
return [self.collectionContext containerInset];
}
- (UIEdgeInsets)adjustedContainerInset {
return [self.collectionContext adjustedContainerInset];
}
- (CGSize)insetContainerSize {
return [self.collectionContext insetContainerSize];
}

View File

@@ -32,7 +32,9 @@
[debug addObject:[NSString stringWithFormat:@"Scroll view delegate: %@", self.scrollViewDelegate]];
[debug addObject:[NSString stringWithFormat:@"Is in update block: %@", IGListDebugBOOL(self.isInUpdateBlock)]];
[debug addObject:[NSString stringWithFormat:@"View controller: %@", self.viewController]];
[debug addObject:[NSString stringWithFormat:@"Is prefetching enabled: %@", IGListDebugBOOL(self.collectionView.isPrefetchingEnabled)]];
if (@available(iOS 10.0, tvOS 10, *)) {
[debug addObject:[NSString stringWithFormat:@"Is prefetching enabled: %@", IGListDebugBOOL(self.collectionView.isPrefetchingEnabled)]];
}
if (self.registeredCellClasses.count > 0) {
[debug addObject:@"Registered cell classes:"];

View File

@@ -176,7 +176,12 @@
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
IGAssert(![self.collectionViewDelegate respondsToSelector:_cmd], @"IGListAdapter is consuming method also implemented by the collectionViewDelegate: %@", NSStringFromSelector(_cmd));
return [self sizeForItemAtIndexPath:indexPath];
CGSize size = [self sizeForItemAtIndexPath:indexPath];
IGAssert(!isnan(size.height), @"IGListAdapter returned NaN height = %f for item at indexPath <%@>", size.height, indexPath);
IGAssert(!isnan(size.width), @"IGListAdapter returned NaN width = %f for item at indexPath <%@>", size.width, indexPath);
return size;
}
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {

View File

@@ -0,0 +1,16 @@
/**
* 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>
@interface UIScrollView (IGListKit)
- (UIEdgeInsets) ig_contentInset;
@end

View File

@@ -0,0 +1,27 @@
/**
* 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 "UIScrollView+IGListKit.h"
@implementation UIScrollView (IGListKit)
- (UIEdgeInsets) ig_contentInset
{
#ifdef __IPHONE_11_0
if (@available(iOS 11.0, tvOS 11.0, *)) {
return self.adjustedContentInset;
} else {
return self.contentInset;
}
#else
return self.contentInset;
#endif
}
@end

2
Pods/Manifest.lock generated
View File

@@ -122,7 +122,7 @@ EXTERNAL SOURCES:
CHECKOUT OPTIONS:
IGListKit:
:commit: 296baf5f854f57150ed12ca5bd8d3903db492734
:commit: 82b52b20502409d3724ab0bdbb36ab562eda9ebd
:git: https://github.com/Instagram/IGListKit.git
SPEC CHECKSUMS:

File diff suppressed because it is too large Load Diff

View File

@@ -36,6 +36,7 @@
#import "IGListBindingSectionControllerDataSource.h"
#import "IGListBindingSectionControllerSelectionDelegate.h"
#import "IGListCollectionContext.h"
#import "IGListCollectionView.h"
#import "IGListCollectionViewLayout.h"
#import "IGListDisplayDelegate.h"
#import "IGListGenericSectionController.h"