Skip to content

Commit

Permalink
[ASCollectionView] synchronous mode (#332)
Browse files Browse the repository at this point in the history
* [ASCollectionView] synchronous mode

* add to changelog

* Update ASDataController.mm

* Update ASCollectionNode.mm
  • Loading branch information
hannahmbanana authored and appleguy committed Jun 6, 2017
1 parent 8115fb9 commit 9ca01b2
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## master

* Add your own contributions to the next release on the line below this with your name.
- Add a synchronous mode to ASCollectionNode, for colletion view data source debugging. [Hannah Troisi](https://github.com/hannahmbanana)
- [ASDisplayNode+Layout] Add check for orphaned nodes after layout transition to clean up. #336. [Scott Goodson](https://github.com/appleguy)
- Fixed an issue where GIFs with placeholders never had their placeholders uncover the GIF. [Garrett Moon](https://github.com/garrettmoon)
- [Yoga] Implement ASYogaLayoutSpec, a simplified integration strategy for Yoga-powered layout calculation. [Scott Goodson](https://github.com/appleguy)
Expand Down
17 changes: 17 additions & 0 deletions Source/ASCollectionNode+Beta.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,23 @@ NS_ASSUME_NONNULL_BEGIN

@property (nonatomic, weak) id<ASBatchFetchingDelegate> batchFetchingDelegate;

/**
* When this mode is enabled, ASCollectionView matches the timing of UICollectionView as closely as possible,
* ensuring that all reload and edit operations are performed on the main thread as blocking calls.
*
* This mode is useful for applications that are debugging issues with their collection view implementation.
* In particular, some applications do not properly conform to the API requirement of UICollectionView, and these
* applications may experience difficulties with ASCollectionView. Providing this mode allows for developers to
* work towards resolving technical debt in their collection view data source, while ramping up asynchronous
* collection layout.
*
* NOTE: Because this mode results in expensive operations like cell layout being performed on the main thread,
* it should be used as a tool to resolve data source conformance issues with Apple collection view API.
*
* @default defaults to NO.
*/
@property (nonatomic, assign) BOOL usesSynchronousDataLoading;

- (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout layoutFacilitator:(nullable id<ASCollectionViewLayoutFacilitatorProtocol>)layoutFacilitator;

- (instancetype)initWithLayoutDelegate:(id<ASCollectionLayoutDelegate>)layoutDelegate layoutFacilitator:(nullable id<ASCollectionViewLayoutFacilitatorProtocol>)layoutFacilitator;
Expand Down
34 changes: 27 additions & 7 deletions Source/ASCollectionNode.mm
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ @interface _ASCollectionPendingState : NSObject
@property (nonatomic, assign) BOOL allowsSelection; // default is YES
@property (nonatomic, assign) BOOL allowsMultipleSelection; // default is NO
@property (nonatomic, assign) BOOL inverted; //default is NO
@property (nonatomic, assign) BOOL usesSynchronousDataLoading;
@property (nonatomic, assign) CGFloat leadingScreensForBatching;
@property (weak, nonatomic) id <ASCollectionViewLayoutInspecting> layoutInspector;
@end
Expand Down Expand Up @@ -175,13 +176,14 @@ - (void)didLoad

if (_pendingState) {
_ASCollectionPendingState *pendingState = _pendingState;
self.pendingState = nil;
view.asyncDelegate = pendingState.delegate;
view.asyncDataSource = pendingState.dataSource;
view.inverted = pendingState.inverted;
view.allowsSelection = pendingState.allowsSelection;
view.allowsMultipleSelection = pendingState.allowsMultipleSelection;
view.layoutInspector = pendingState.layoutInspector;
view.asyncDelegate = pendingState.delegate;
view.asyncDataSource = pendingState.dataSource;
view.inverted = pendingState.inverted;
view.allowsSelection = pendingState.allowsSelection;
view.allowsMultipleSelection = pendingState.allowsMultipleSelection;
view.usesSynchronousDataLoading = pendingState.usesSynchronousDataLoading;
view.layoutInspector = pendingState.layoutInspector;
self.pendingState = nil;

if (pendingState.rangeMode != ASLayoutRangeModeUnspecified) {
[view.rangeController updateCurrentRangeWithMode:pendingState.rangeMode];
Expand Down Expand Up @@ -464,6 +466,24 @@ - (void)setBatchFetchingDelegate:(id<ASBatchFetchingDelegate>)batchFetchingDeleg
return _batchFetchingDelegate;
}

- (BOOL)usesSynchronousDataLoading
{
if ([self pendingState]) {
return _pendingState.usesSynchronousDataLoading;
} else {
return self.view.usesSynchronousDataLoading;
}
}

- (void)setUsesSynchronousDataLoading:(BOOL)usesSynchronousDataLoading
{
if ([self pendingState]) {
_pendingState.usesSynchronousDataLoading = usesSynchronousDataLoading;
} else {
self.view.usesSynchronousDataLoading = usesSynchronousDataLoading;
}
}

#pragma mark - Range Tuning

- (ASRangeTuningParameters)tuningParametersForRangeType:(ASLayoutRangeType)rangeType
Expand Down
10 changes: 10 additions & 0 deletions Source/ASCollectionView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -767,6 +767,16 @@ - (NSArray *)visibleNodes
return visibleNodes;
}

- (BOOL)usesSynchronousDataLoading
{
return self.dataController.usesSynchronousDataLoading;
}

- (void)setUsesSynchronousDataLoading:(BOOL)usesSynchronousDataLoading
{
self.dataController.usesSynchronousDataLoading = usesSynchronousDataLoading;
}

#pragma mark Internal

- (void)_configureCollectionViewLayout:(nonnull UICollectionViewLayout *)layout
Expand Down
5 changes: 5 additions & 0 deletions Source/Details/ASCollectionInternal.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, strong, readonly) ASDataController *dataController;
@property (nonatomic, strong, readonly) ASRangeController *rangeController;

/**
* @see ASCollectionNode+Beta.h for full documentation.
*/
@property (nonatomic, assign) BOOL usesSynchronousDataLoading;

/**
* Attempt to get the view-layer index path for the item with the given index path.
*
Expand Down
5 changes: 5 additions & 0 deletions Source/Details/ASDataController.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,11 @@ extern NSString * const ASCollectionInvalidUpdateException;
@property (nonatomic, strong, readonly) ASEventLog *eventLog;
#endif

/**
* @see ASCollectionNode+Beta.h for full documentation.
*/
@property (nonatomic, assign) BOOL usesSynchronousDataLoading;

/** @name Data Updating */

- (void)updateWithChangeSet:(_ASHierarchyChangeSet *)changeSet;
Expand Down
4 changes: 4 additions & 0 deletions Source/Details/ASDataController.mm
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,10 @@ - (void)updateWithChangeSet:(_ASHierarchyChangeSet *)changeSet
}];
}];
});

if (_usesSynchronousDataLoading) {
[self waitUntilAllUpdatesAreCommitted];
}
}

/**
Expand Down

0 comments on commit 9ca01b2

Please sign in to comment.