Merge pull request #603 from nguyenhuy/improved_external_relayout

Improve relayout when constrained size of all nodes is changed
This commit is contained in:
appleguy 2015-08-15 22:07:50 -07:00
commit 3983bf2289
8 changed files with 27 additions and 87 deletions

View File

@ -125,7 +125,7 @@ static BOOL _isInterceptedSelector(SEL sel)
ASBatchContext *_batchContext; ASBatchContext *_batchContext;
BOOL _pendingRelayoutForAllRows; CGSize _maxSizeForNodesConstrainedSize;
} }
@property (atomic, assign) BOOL asyncDataSourceLocked; @property (atomic, assign) BOOL asyncDataSourceLocked;
@ -170,16 +170,13 @@ static BOOL _isInterceptedSelector(SEL sel)
_performingBatchUpdates = NO; _performingBatchUpdates = NO;
_batchUpdateBlocks = [NSMutableArray array]; _batchUpdateBlocks = [NSMutableArray array];
_collectionViewLayoutImplementsInsetSection = [layout respondsToSelector:@selector(sectionInset)];
_maxSizeForNodesConstrainedSize = self.bounds.size;
[self registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"_ASCollectionViewCell"]; [self registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"_ASCollectionViewCell"];
if (ASSystemVersionLessThan8()) {
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationDidChange) name:UIDeviceOrientationDidChangeNotification object:nil];
}
_collectionViewLayoutImplementsInsetSection = [layout respondsToSelector:@selector(sectionInset)];
return self; return self;
} }
@ -189,11 +186,6 @@ static BOOL _isInterceptedSelector(SEL sel)
// This bug might be iOS 7-specific. // This bug might be iOS 7-specific.
super.delegate = nil; super.delegate = nil;
super.dataSource = nil; super.dataSource = nil;
if (ASSystemVersionLessThan8()) {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
}
} }
#pragma mark - #pragma mark -
@ -480,26 +472,12 @@ static BOOL _isInterceptedSelector(SEL sel)
} }
} }
#pragma mark -
#pragma mark Orientation Change Handling
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection
{
_pendingRelayoutForAllRows = YES;
}
- (void)deviceOrientationDidChange
{
_pendingRelayoutForAllRows = YES;
}
- (void)layoutSubviews - (void)layoutSubviews
{ {
[super layoutSubviews]; [super layoutSubviews];
if (_pendingRelayoutForAllRows) { if (! CGSizeEqualToSize(_maxSizeForNodesConstrainedSize, self.bounds.size)) {
_pendingRelayoutForAllRows = NO; _maxSizeForNodesConstrainedSize = self.bounds.size;
[self performBatchAnimated:NO updates:^{ [self performBatchAnimated:NO updates:^{
[_dataController relayoutAllRows]; [_dataController relayoutAllRows];
} completion:nil]; } completion:nil];
@ -562,7 +540,7 @@ static BOOL _isInterceptedSelector(SEL sel)
if (_asyncDataSourceImplementsConstrainedSizeForNode) { if (_asyncDataSourceImplementsConstrainedSizeForNode) {
constrainedSize = [_asyncDataSource collectionView:self constrainedSizeForNodeAtIndexPath:indexPath]; constrainedSize = [_asyncDataSource collectionView:self constrainedSizeForNodeAtIndexPath:indexPath];
} else { } else {
CGSize maxSize = self.bounds.size; CGSize maxSize = _maxSizeForNodesConstrainedSize;
if (ASScrollDirectionContainsHorizontalDirection([self scrollableDirections])) { if (ASScrollDirectionContainsHorizontalDirection([self scrollableDirections])) {
maxSize.width = FLT_MAX; maxSize.width = FLT_MAX;
} else { } else {

View File

@ -146,9 +146,9 @@ static BOOL _isInterceptedSelector(SEL sel)
NSIndexPath *_contentOffsetAdjustmentTopVisibleRow; NSIndexPath *_contentOffsetAdjustmentTopVisibleRow;
CGFloat _contentOffsetAdjustment; CGFloat _contentOffsetAdjustment;
BOOL _pendingRelayoutForAllRows;
BOOL _asyncDataSourceImplementsConstrainedSizeForNode; BOOL _asyncDataSourceImplementsConstrainedSizeForNode;
CGFloat _maxWidthForNodesConstrainedSize;
} }
@property (atomic, assign) BOOL asyncDataSourceLocked; @property (atomic, assign) BOOL asyncDataSourceLocked;
@ -202,10 +202,7 @@ void ASPerformBlockWithoutAnimation(BOOL withoutAnimation, void (^block)()) {
_automaticallyAdjustsContentOffset = NO; _automaticallyAdjustsContentOffset = NO;
if (ASSystemVersionLessThan8()) { _maxWidthForNodesConstrainedSize = self.bounds.size.width;
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationDidChange) name:UIDeviceOrientationDidChangeNotification object:nil];
}
} }
- (instancetype)initWithFrame:(CGRect)frame style:(UITableViewStyle)style - (instancetype)initWithFrame:(CGRect)frame style:(UITableViewStyle)style
@ -243,11 +240,6 @@ void ASPerformBlockWithoutAnimation(BOOL withoutAnimation, void (^block)()) {
// This bug might be iOS 7-specific. // This bug might be iOS 7-specific.
super.delegate = nil; super.delegate = nil;
super.dataSource = nil; super.dataSource = nil;
if (ASSystemVersionLessThan8()) {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
}
} }
#pragma mark - #pragma mark -
@ -373,25 +365,12 @@ void ASPerformBlockWithoutAnimation(BOOL withoutAnimation, void (^block)()) {
[_dataController endUpdatesAnimated:animated completion:completion]; [_dataController endUpdatesAnimated:animated completion:completion];
} }
#pragma mark -
#pragma mark Orientation Change Handling
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection
{
_pendingRelayoutForAllRows = YES;
}
- (void)deviceOrientationDidChange
{
_pendingRelayoutForAllRows = YES;
}
- (void)layoutSubviews - (void)layoutSubviews
{ {
[super layoutSubviews]; [super layoutSubviews];
if (_pendingRelayoutForAllRows) { if (_maxWidthForNodesConstrainedSize != self.bounds.size.width) {
_pendingRelayoutForAllRows = NO; _maxWidthForNodesConstrainedSize = self.bounds.size.width;
[self beginUpdates]; [self beginUpdates];
[_dataController relayoutAllRows]; [_dataController relayoutAllRows];
[self endUpdates]; [self endUpdates];
@ -812,7 +791,7 @@ void ASPerformBlockWithoutAnimation(BOOL withoutAnimation, void (^block)()) {
} }
// Default size range // Default size range
return ASSizeRangeMake(CGSizeZero, CGSizeMake(self.bounds.size.width, FLT_MAX)); return ASSizeRangeMake(CGSizeZero, CGSizeMake(_maxWidthForNodesConstrainedSize, FLT_MAX));
} }
- (void)dataControllerLockDataSource - (void)dataControllerLockDataSource

View File

@ -156,8 +156,8 @@ typedef NSUInteger ASDataControllerAnimationOptions;
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions; - (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions;
/** /**
* Re-measures all loaded nodes. Used for external relayout (relayout that is caused by a change in constrained size of each and every cell node, * Re-measures all loaded nodes. Used to respond to a change in size of the containing view
* for example, after an orientation change). * (e.g. ASTableView or ASCollectionView after an orientation change).
*/ */
- (void)relayoutAllRows; - (void)relayoutAllRows;

View File

@ -564,15 +564,14 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
LOG(@"Edit Command - relayoutRows"); LOG(@"Edit Command - relayoutRows");
[_editingTransactionQueue waitUntilAllOperationsAreFinished]; [_editingTransactionQueue waitUntilAllOperationsAreFinished];
NSArray *indexPaths = ASIndexPathsForMultidimensionalArray(_completedNodes); [_completedNodes enumerateObjectsUsingBlock:^(NSMutableArray *section, NSUInteger sectionIndex, BOOL *stop) {
NSArray *loadedNodes = ASFindElementsInMultidimensionalArrayAtIndexPaths(_completedNodes, indexPaths); [section enumerateObjectsUsingBlock:^(ASCellNode *node, NSUInteger rowIndex, BOOL *stop) {
ASSizeRange constrainedSize = [_dataSource dataController:self
for (NSUInteger i = 0; i < loadedNodes.count && i < indexPaths.count; i++) { constrainedSizeForNodeAtIndexPath:[NSIndexPath indexPathForRow:rowIndex inSection:sectionIndex]];
ASSizeRange constrainedSize = [_dataSource dataController:self constrainedSizeForNodeAtIndexPath:indexPaths[i]]; [node measureWithSizeRange:constrainedSize];
ASCellNode *node = loadedNodes[i]; node.frame = CGRectMake(0.0f, 0.0f, node.calculatedSize.width, node.calculatedSize.height);
[node measureWithSizeRange:constrainedSize]; }];
node.frame = CGRectMake(0.0f, 0.0f, node.calculatedSize.width, node.calculatedSize.height); }];
}
}]; }];
} }

View File

@ -24,8 +24,4 @@ CGFloat ASCeilPixelValue(CGFloat f);
CGFloat ASRoundPixelValue(CGFloat f); CGFloat ASRoundPixelValue(CGFloat f);
BOOL ASSystemVersionLessThan8();
BOOL ASSystemVersionLessThanVersion(NSString *version);
ASDISPLAYNODE_EXTERN_C_END ASDISPLAYNODE_EXTERN_C_END

View File

@ -61,18 +61,3 @@ CGFloat ASRoundPixelValue(CGFloat f)
{ {
return roundf(f * ASScreenScale()) / ASScreenScale(); return roundf(f * ASScreenScale()) / ASScreenScale();
} }
BOOL ASSystemVersionLessThan8()
{
static BOOL lessThan8;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
lessThan8 = ASSystemVersionLessThanVersion(@"8");
});
return lessThan8;
}
BOOL ASSystemVersionLessThanVersion(NSString *version)
{
return [[[UIDevice currentDevice] systemVersion] compare:version options:NSNumericSearch] == NSOrderedAscending;
}

View File

@ -314,6 +314,7 @@
IPHONEOS_DEPLOYMENT_TARGET = 7.1; IPHONEOS_DEPLOYMENT_TARGET = 7.1;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
TARGETED_DEVICE_FAMILY = "1,2";
}; };
name = Debug; name = Debug;
}; };
@ -326,6 +327,7 @@
IPHONEOS_DEPLOYMENT_TARGET = 7.1; IPHONEOS_DEPLOYMENT_TARGET = 7.1;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
TARGETED_DEVICE_FAMILY = "1,2";
}; };
name = Release; name = Release;
}; };

View File

@ -59,6 +59,7 @@ static const NSInteger kMaxLitterSize = 100; // max number of kitten cell
_blurbNodeIndexPath = [NSIndexPath indexPathForItem:0 inSection:0]; _blurbNodeIndexPath = [NSIndexPath indexPathForItem:0 inSection:0];
self.title = @"Kittens";
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit
target:self target:self
action:@selector(toggleEditingMode)]; action:@selector(toggleEditingMode)];