-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
avoid crashing when not subclassing IGListSectionController
Summary: Currently, if you use `IGListSectionController` without a subclass, `UICollectionView` will crash when requesting the cell. That's because `[IGListSectionController numberOfItems]` defaults to 1, but returns no cell. There's a few issues with that: 1. It can be tough to debug, because the crash in within `UICollectionView`. We don't know the dataSource or object type responsible. 2. The crash only happens if the user scrolls by the missing cell, which can make it hard to repro. 3. If we don't know how to render a single section, we might not want to crash the entire app. Passing a plain `IGListSectionController` kind of feels like the dataSource is ok with just rendering nothing. It's not clear at all that it will crash. Options: 1. Crash immediately when a plain `IGListSectionController` is passed to `IGListAdapter`, so we get a clear callstack and API feedback. If the dataSource doesn't want to crash, it must return `IGEmptySectionController` that has 0 `numberOfItems`. 2. Don't crash, but log a `IGFailAssert()`. If the dataSource wants to throw on a missing object-controller match, they can can, but it's not the IGListKit default. I'm leaning on #2 for a few reasons. It's really not obvious that passing a plain `IGListSectionController` would crash and no one will know that `IGEmptySectionController` exists. We could have a linter, but that only works within Meta. Reviewed By: DimaVartanian Differential Revision: D52087286 fbshipit-source-id: 8b8754d56e66c0c2b00f8df3b9671a6fc2287aea
- Loading branch information
1 parent
f99d861
commit 6ea2b91
Showing
7 changed files
with
105 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
/* | ||
* Copyright (c) Meta Platforms, Inc. and affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
#import <UIKit/UIKit.h> | ||
|
||
NS_ASSUME_NONNULL_BEGIN | ||
|
||
/// Layout that 1) creates all attributes regardless of size, and 2) positions them with origin (0,0) | ||
@interface IGListTestCollectionViewLayout : UICollectionViewLayout | ||
|
||
@end | ||
|
||
NS_ASSUME_NONNULL_END |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
/* | ||
* Copyright (c) Meta Platforms, Inc. and affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
#import "IGListTestCollectionViewLayout.h" | ||
|
||
@implementation IGListTestCollectionViewLayout { | ||
NSDictionary<NSIndexPath *, UICollectionViewLayoutAttributes *> *_attributes; | ||
} | ||
|
||
- (void)prepareLayout { | ||
UICollectionView *const collectionView = self.collectionView; | ||
|
||
// Get the UICollectionViewDelegateFlowLayout for sizes | ||
if (![collectionView.delegate conformsToProtocol:@protocol(UICollectionViewDelegateFlowLayout)]) { | ||
_attributes = nil; | ||
return; | ||
} | ||
const id<UICollectionViewDelegateFlowLayout> flowDelegate = (id<UICollectionViewDelegateFlowLayout>)collectionView.delegate; | ||
|
||
// Create the attributes | ||
NSMutableDictionary<NSIndexPath *, UICollectionViewLayoutAttributes *> *const attributes = [NSMutableDictionary new]; | ||
const NSInteger numberOfSections = collectionView.numberOfSections; | ||
|
||
for (NSInteger section = 0; section < numberOfSections; section++) { | ||
const NSInteger numberOfItems = [collectionView numberOfItemsInSection:section]; | ||
for (NSInteger item = 0; item < numberOfItems; item++) { | ||
NSIndexPath *const indexPath = [NSIndexPath indexPathForItem:item inSection:section]; | ||
UICollectionViewLayoutAttributes *const attribute = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]; | ||
const CGSize size = [flowDelegate collectionView:collectionView layout:self sizeForItemAtIndexPath:indexPath]; | ||
attribute.frame = CGRectMake(0, 0, size.width, size.height); | ||
attributes[indexPath] = attribute; | ||
} | ||
} | ||
|
||
_attributes = [attributes copy]; | ||
} | ||
|
||
- (nullable NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect { | ||
NSMutableArray<UICollectionViewLayoutAttributes *> *attributes = [NSMutableArray new]; | ||
[_attributes enumerateKeysAndObjectsUsingBlock:^(NSIndexPath *indexPath, UICollectionViewLayoutAttributes *attribute, BOOL* stop) { | ||
if (CGRectIntersectsRect(attribute.frame, rect)) { | ||
[attributes addObject:attribute]; | ||
} | ||
}]; | ||
return [attributes copy]; | ||
} | ||
|
||
- (nullable UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath { | ||
return _attributes[indexPath]; | ||
} | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters