From 49d12622bba6a82b36747f3ea7c357a43a9a7e29 Mon Sep 17 00:00:00 2001 From: Huy Nguyen Date: Mon, 3 Apr 2017 16:03:03 +0100 Subject: [PATCH] Address other comments --- AsyncDisplayKit.xcodeproj/project.pbxproj | 14 ++--- Source/Details/ASCollectionFlowLayout.h | 6 +++ Source/Details/ASCollectionFlowLayout.m | 37 +------------ .../Details/ASCollectionLayout+Subclasses.h | 5 +- Source/Details/ASCollectionLayout.h | 2 - Source/Details/ASCollectionLayout.mm | 53 +++++++++++-------- Source/Details/ASCollectionLayoutHelpers.h | 13 ----- Source/Details/ASCollectionLayoutHelpers.m | 37 ------------- Source/Details/ASCollectionLayoutState.h | 16 +++++- Source/Details/ASCollectionLayoutState.m | 26 +++++++++ Source/Private/ASTwoDimensionalArrayUtils.m | 9 ++-- 11 files changed, 89 insertions(+), 129 deletions(-) delete mode 100644 Source/Details/ASCollectionLayoutHelpers.h delete mode 100644 Source/Details/ASCollectionLayoutHelpers.m diff --git a/AsyncDisplayKit.xcodeproj/project.pbxproj b/AsyncDisplayKit.xcodeproj/project.pbxproj index 31c697d45e..27e3badaf7 100644 --- a/AsyncDisplayKit.xcodeproj/project.pbxproj +++ b/AsyncDisplayKit.xcodeproj/project.pbxproj @@ -375,8 +375,6 @@ E597E3C61E817B2800451596 /* ASCollectionLayout+Subclasses.h in Headers */ = {isa = PBXBuildFile; fileRef = E597E3C51E817B2800451596 /* ASCollectionLayout+Subclasses.h */; }; E597E3C81E817FB500451596 /* ASDataControllerLayoutContext.h in Headers */ = {isa = PBXBuildFile; fileRef = E597E3C71E817FB500451596 /* ASDataControllerLayoutContext.h */; }; E597E3CA1E81800500451596 /* ASDataControllerLayoutContext.m in Sources */ = {isa = PBXBuildFile; fileRef = E597E3C91E81800500451596 /* ASDataControllerLayoutContext.m */; }; - E5ABAC761E8551B3007AC15C /* ASCollectionLayoutHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = E5ABAC751E8551B3007AC15C /* ASCollectionLayoutHelpers.h */; }; - E5ABAC781E85528A007AC15C /* ASCollectionLayoutHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = E5ABAC771E85528A007AC15C /* ASCollectionLayoutHelpers.m */; }; E5ABAC7B1E8564EE007AC15C /* ASRectTable.h in Headers */ = {isa = PBXBuildFile; fileRef = E5ABAC791E8564EE007AC15C /* ASRectTable.h */; }; E5ABAC7C1E8564EE007AC15C /* ASRectTable.m in Sources */ = {isa = PBXBuildFile; fileRef = E5ABAC7A1E8564EE007AC15C /* ASRectTable.m */; }; E5B077E61E6843A600C24B5B /* ASCollectionLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = E5B077E11E6843A600C24B5B /* ASCollectionLayout.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -786,19 +784,17 @@ E5711A2D1C840C96009619D4 /* ASCollectionElement.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASCollectionElement.mm; sourceTree = ""; }; E579BC961E84203D00E24C78 /* ASCollectionNode+FrameworkPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASCollectionNode+FrameworkPrivate.h"; sourceTree = ""; }; E597E3C31E81748900451596 /* ASDataController+Beta.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASDataController+Beta.h"; sourceTree = ""; }; - E597E3C51E817B2800451596 /* ASCollectionLayout+Subclasses.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASCollectionLayout+Subclasses.h"; sourceTree = ""; }; + E597E3C51E817B2800451596 /* ASCollectionLayout+Subclasses.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = "ASCollectionLayout+Subclasses.h"; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; E597E3C71E817FB500451596 /* ASDataControllerLayoutContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASDataControllerLayoutContext.h; sourceTree = ""; }; E597E3C91E81800500451596 /* ASDataControllerLayoutContext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASDataControllerLayoutContext.m; sourceTree = ""; }; - E5ABAC751E8551B3007AC15C /* ASCollectionLayoutHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCollectionLayoutHelpers.h; sourceTree = ""; }; - E5ABAC771E85528A007AC15C /* ASCollectionLayoutHelpers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASCollectionLayoutHelpers.m; sourceTree = ""; }; E5ABAC791E8564EE007AC15C /* ASRectTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASRectTable.h; sourceTree = ""; }; E5ABAC7A1E8564EE007AC15C /* ASRectTable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASRectTable.m; sourceTree = ""; }; E5B077E11E6843A600C24B5B /* ASCollectionLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCollectionLayout.h; sourceTree = ""; }; - E5B077F41E68576B00C24B5B /* ASCollectionLayout.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASCollectionLayout.mm; sourceTree = ""; }; + E5B077F41E68576B00C24B5B /* ASCollectionLayout.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASCollectionLayout.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; E5B077FD1E69F4EB00C24B5B /* ASElementMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASElementMap.h; sourceTree = ""; }; E5B077FE1E69F4EB00C24B5B /* ASElementMap.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASElementMap.m; sourceTree = ""; }; E5B0780A1E6A01E200C24B5B /* ASCollectionFlowLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCollectionFlowLayout.h; sourceTree = ""; }; - E5B0780B1E6A01E200C24B5B /* ASCollectionFlowLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASCollectionFlowLayout.m; sourceTree = ""; }; + E5B0780B1E6A01E200C24B5B /* ASCollectionFlowLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ASCollectionFlowLayout.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; E5E281731E71C833006B67C2 /* ASCollectionLayoutState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCollectionLayoutState.h; sourceTree = ""; }; E5E281751E71C845006B67C2 /* ASCollectionLayoutState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASCollectionLayoutState.m; sourceTree = ""; }; EFA731F0396842FF8AB635EE /* libPods-AsyncDisplayKitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AsyncDisplayKitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1420,8 +1416,6 @@ E5B077F41E68576B00C24B5B /* ASCollectionLayout.mm */, E5B0780A1E6A01E200C24B5B /* ASCollectionFlowLayout.h */, E5B0780B1E6A01E200C24B5B /* ASCollectionFlowLayout.m */, - E5ABAC751E8551B3007AC15C /* ASCollectionLayoutHelpers.h */, - E5ABAC771E85528A007AC15C /* ASCollectionLayoutHelpers.m */, ); name = "Collection Layout"; sourceTree = ""; @@ -1548,7 +1542,6 @@ B35062521B010EFD0018CF92 /* ASDisplayNodeInternal.h in Headers */, AC7A2C181BDE11DF0093FE1A /* ASTableViewInternal.h in Headers */, B35062531B010EFD0018CF92 /* ASImageNode+CGExtras.h in Headers */, - E5ABAC761E8551B3007AC15C /* ASCollectionLayoutHelpers.h in Headers */, 254C6B7F1BF94DF4003EC431 /* ASTextKitTruncating.h in Headers */, CC58AA4B1E398E1D002C8CB4 /* ASBlockTypes.h in Headers */, 6977965F1D8AC8D3007E93D7 /* ASLayoutSpec+Subclasses.h in Headers */, @@ -1994,7 +1987,6 @@ DB78412E1C6BCE1600A9E2B4 /* _ASTransitionContext.m in Sources */, B350620B1B010EFD0018CF92 /* ASTableView.mm in Sources */, B350620E1B010EFD0018CF92 /* ASTextNode.mm in Sources */, - E5ABAC781E85528A007AC15C /* ASCollectionLayoutHelpers.m in Sources */, 6959433F1D70815300B0EE1F /* ASDisplayNodeLayout.mm in Sources */, 68355B3E1CB57A60001D4E68 /* ASPINRemoteImageDownloader.m in Sources */, CC034A141E649F1300626263 /* AsyncDisplayKit+IGListKitMethods.m in Sources */, diff --git a/Source/Details/ASCollectionFlowLayout.h b/Source/Details/ASCollectionFlowLayout.h index da3298c8d9..c850fba61b 100644 --- a/Source/Details/ASCollectionFlowLayout.h +++ b/Source/Details/ASCollectionFlowLayout.h @@ -9,8 +9,14 @@ #import #import +NS_ASSUME_NONNULL_BEGIN + +AS_SUBCLASSING_RESTRICTED + @interface ASCollectionFlowLayout : ASCollectionLayout - (instancetype)initWithScrollableDirections:(ASScrollDirection)scrollableDirections; @end + +NS_ASSUME_NONNULL_END diff --git a/Source/Details/ASCollectionFlowLayout.m b/Source/Details/ASCollectionFlowLayout.m index 15ce0a4840..5a5921922d 100644 --- a/Source/Details/ASCollectionFlowLayout.m +++ b/Source/Details/ASCollectionFlowLayout.m @@ -11,7 +11,6 @@ #import #import #import -#import #import #import #import @@ -53,7 +52,7 @@ - (ASSizeRange)sizeRangeThatFits:(CGSize)viewportSize return sizeRange; } -- (ASCollectionLayoutState *)calculateLayoutForLayoutContext:(ASDataControllerLayoutContext *)context +- (ASCollectionLayoutState *)calculateLayoutWithContext:(ASDataControllerLayoutContext *)context { ASElementMap *elementMap = context.elementMap; NSMutableArray *children = ASArrayByFlatMapping(elementMap.itemElements, ASCollectionElement *element, element.node); @@ -72,39 +71,7 @@ - (ASCollectionLayoutState *)calculateLayoutForLayoutContext:(ASDataControllerLa children:children]; stackSpec.concurrent = YES; ASLayout *layout = [stackSpec layoutThatFits:[self sizeRangeThatFits:context.viewportSize]]; - return ASLayoutToCollectionContentAttributes(layout, elementMap); -} - -- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect -{ - NSMutableArray *attributesInRect = [NSMutableArray array]; - NSMapTable *attrsMap = self.currentContentAttributes.elementToLayoutArrtibutesMap; - for (ASCollectionElement *element in attrsMap) { - UICollectionViewLayoutAttributes *attrs = [attrsMap objectForKey:element]; - if (CGRectIntersectsRect(rect, attrs.frame)) { - [attributesInRect addObject:attrs]; - } - } - return attributesInRect; -} - -- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath -{ - ASCollectionLayoutState *state = self.currentContentAttributes; - ASCollectionElement *element = [state.elementMap elementForItemAtIndexPath:indexPath]; - return [state.elementToLayoutArrtibutesMap objectForKey:element]; -} - -- (UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath -{ - ASCollectionLayoutState *state = self.currentContentAttributes; - ASCollectionElement *element = [state.elementMap supplementaryElementOfKind:elementKind atIndexPath:indexPath]; - return [state.elementToLayoutArrtibutesMap objectForKey:element]; -} - -- (UICollectionViewLayoutAttributes *)layoutAttributesForDecorationViewOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath -{ - return [self layoutAttributesForSupplementaryViewOfKind:elementKind atIndexPath:indexPath]; + return [[ASCollectionLayoutState alloc] initWithElementMap:elementMap layout:layout]; } @end diff --git a/Source/Details/ASCollectionLayout+Subclasses.h b/Source/Details/ASCollectionLayout+Subclasses.h index 03785df587..a4ec90bfb0 100644 --- a/Source/Details/ASCollectionLayout+Subclasses.h +++ b/Source/Details/ASCollectionLayout+Subclasses.h @@ -15,9 +15,6 @@ NS_ASSUME_NONNULL_BEGIN @interface ASCollectionLayout () -/// The current state of this layout object, if any. This property must be accessed on main thread. -@property (nonatomic, strong, nullable) ASCollectionLayoutState *state; - /** * @abstract Prepares and returns a new layout for given context. * @@ -32,7 +29,7 @@ NS_ASSUME_NONNULL_BEGIN * * @discussion This method must block its calling thread but can dispatch to other theads to reduce blocking time. */ -- (ASCollectionLayoutState *)calculateLayoutForLayoutContext:(ASDataControllerLayoutContext *)context; +- (ASCollectionLayoutState *)calculateLayoutWithContext:(ASDataControllerLayoutContext *)context; @end diff --git a/Source/Details/ASCollectionLayout.h b/Source/Details/ASCollectionLayout.h index d71b0c0813..e973f798b0 100644 --- a/Source/Details/ASCollectionLayout.h +++ b/Source/Details/ASCollectionLayout.h @@ -39,8 +39,6 @@ NS_ASSUME_NONNULL_BEGIN */ @property (nonatomic, weak) ASCollectionNode *collectionNode; -- (instancetype)init NS_DESIGNATED_INITIALIZER; - - (instancetype)initWithCoder:(NSCoder *)aDecoder __unavailable; @end diff --git a/Source/Details/ASCollectionLayout.mm b/Source/Details/ASCollectionLayout.mm index a108a7cf34..6e92b45b3a 100644 --- a/Source/Details/ASCollectionLayout.mm +++ b/Source/Details/ASCollectionLayout.mm @@ -35,25 +35,6 @@ @interface ASCollectionLayout () { @implementation ASCollectionLayout -- (instancetype)init -{ - return [super init]; -} - -- (ASCollectionLayoutState *)state -{ - ASDisplayNodeAssertMainThread(); - return _state; -} - -- (void)setState:(ASCollectionLayoutState *)newState -{ - ASDisplayNodeAssertMainThread(); - if (! ASObjectIsEqual(_state, newState)) { - _state = newState; - } -} - #pragma mark - ASDataControllerLayoutDelegate - (ASDataControllerLayoutContext *)layoutContextWithElementMap:(ASElementMap *)map @@ -64,7 +45,7 @@ - (ASDataControllerLayoutContext *)layoutContextWithElementMap:(ASElementMap *)m - (void)prepareLayoutForLayoutContext:(ASDataControllerLayoutContext *)context { - ASCollectionLayoutState *state = [self calculateLayoutForLayoutContext:context]; + ASCollectionLayoutState *state = [self calculateLayoutWithContext:context]; ASDN::MutexLocker l(__instanceLock__); _pendingState = state; @@ -90,7 +71,7 @@ - (void)prepareLayout } if (state == nil) { - state = [self calculateLayoutForLayoutContext:context]; + state = [self calculateLayoutWithContext:context]; } _state = state; @@ -106,12 +87,40 @@ - (void)invalidateLayout - (CGSize)collectionViewContentSize { ASDisplayNodeAssertMainThread(); + ASDisplayNodeAssertNotNil(_state, @"Collection layout state should not be nil at this point"); return _state.contentSize; } +- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect +{ + NSMutableArray *attributesInRect = [NSMutableArray array]; + NSMapTable *attrsMap = _state.elementToLayoutArrtibutesMap; + for (ASCollectionElement *element in attrsMap) { + UICollectionViewLayoutAttributes *attrs = [attrsMap objectForKey:element]; + if (CGRectIntersectsRect(rect, attrs.frame)) { + [attributesInRect addObject:attrs]; + } + } + return attributesInRect; +} + +- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath +{ + ASCollectionLayoutState *state = _state; + ASCollectionElement *element = [state.elementMap elementForItemAtIndexPath:indexPath]; + return [state.elementToLayoutArrtibutesMap objectForKey:element]; +} + +- (UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath +{ + ASCollectionLayoutState *state = _state; + ASCollectionElement *element = [state.elementMap supplementaryElementOfKind:elementKind atIndexPath:indexPath]; + return [state.elementToLayoutArrtibutesMap objectForKey:element]; +} + #pragma mark - Subclass hooks -- (ASCollectionLayoutState *)calculateLayoutForLayoutContext:(ASDataControllerLayoutContext *)context +- (ASCollectionLayoutState *)calculateLayoutWithContext:(ASDataControllerLayoutContext *)context { // Subclass hooks ASDisplayNodeAssertLockUnownedByCurrentThread(__instanceLock__); diff --git a/Source/Details/ASCollectionLayoutHelpers.h b/Source/Details/ASCollectionLayoutHelpers.h deleted file mode 100644 index 8a73a1f55e..0000000000 --- a/Source/Details/ASCollectionLayoutHelpers.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// ASCollectionLayoutHelpers.h -// AsyncDisplayKit -// -// Created by Huy Nguyen on 24/3/17. -// Copyright © 2017 Facebook. All rights reserved. -// - -#import - -@class ASCollectionLayoutState, ASLayout, ASElementMap; - -extern AS_WARN_UNUSED_RESULT ASCollectionLayoutState *ASLayoutToCollectionContentAttributes(ASLayout *layout, ASElementMap *elementMap); diff --git a/Source/Details/ASCollectionLayoutHelpers.m b/Source/Details/ASCollectionLayoutHelpers.m deleted file mode 100644 index 6f824f3e71..0000000000 --- a/Source/Details/ASCollectionLayoutHelpers.m +++ /dev/null @@ -1,37 +0,0 @@ -// -// ASCollectionLayoutHelpers.m -// AsyncDisplayKit -// -// Created by Huy Nguyen on 24/3/17. -// Copyright © 2017 Facebook. All rights reserved. -// - -#import - -#import -#import -#import -#import -#import - -ASCollectionLayoutState *ASLayoutToCollectionContentAttributes(ASLayout *layout, ASElementMap *elementMap) -{ - NSMapTable *attrsMap = [NSMapTable weakToStrongObjectsMapTable]; - for (ASLayout *sublayout in layout.sublayouts) { - ASCollectionElement *element = ((ASCellNode *)sublayout.layoutElement).collectionElement; - NSIndexPath *indexPath = [elementMap indexPathForElement:element]; - - UICollectionViewLayoutAttributes *attrs; - if (element.supplementaryElementKind == nil) { - attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]; - } else { - attrs = [UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:element.supplementaryElementKind withIndexPath:indexPath]; - } - - attrs.frame = sublayout.frame; - [attrsMap setObject:attrs forKey:element]; - } - - return [[ASCollectionLayoutState alloc] initWithElementMap:elementMap contentSize:layout.size elementToLayoutArrtibutesMap:attrsMap]; -} - diff --git a/Source/Details/ASCollectionLayoutState.h b/Source/Details/ASCollectionLayoutState.h index 6a57e0927b..efcf896143 100644 --- a/Source/Details/ASCollectionLayoutState.h +++ b/Source/Details/ASCollectionLayoutState.h @@ -10,7 +10,7 @@ #import #import -@class ASElementMap, ASCollectionElement; +@class ASElementMap, ASCollectionElement, ASLayout; NS_ASSUME_NONNULL_BEGIN @@ -33,10 +33,22 @@ AS_SUBCLASSING_RESTRICTED * * @param contentSize The content size of the collection's layout * - * @param elementToLayoutArrtibutesMap Map between elements to their layout attributes. The map may contain all elements, or a subset of them and to be updated later. Should use weak pointers for elements. + * @param elementToLayoutArrtibutesMap Map between elements to their layout attributes. The map may contain all elements, or a subset of them and will be updated later. + * Also, it should have NSMapTableObjectPointerPersonality and NSMapTableWeakMemory as key options. */ - (instancetype)initWithElementMap:(ASElementMap *)elementMap contentSize:(CGSize)contentSize elementToLayoutArrtibutesMap:(NSMapTable *)attrsMap NS_DESIGNATED_INITIALIZER; +/** + * Convenience initializer. + * + * @param elementMap The element map used to calculate this object + * + * @param layout The layout describes size and position of all elements, or a subset of them and will be updated later. + * + * @discussion The sublayouts that describe position of elements must be direct children of the root layout object parameter. + */ +- (instancetype)initWithElementMap:(ASElementMap *)elementMap layout:(ASLayout *)layout; + @end NS_ASSUME_NONNULL_END diff --git a/Source/Details/ASCollectionLayoutState.m b/Source/Details/ASCollectionLayoutState.m index 0076c9dd99..9becad58b3 100644 --- a/Source/Details/ASCollectionLayoutState.m +++ b/Source/Details/ASCollectionLayoutState.m @@ -7,11 +7,37 @@ // #import + #import +#import +#import #import +#import @implementation ASCollectionLayoutState +- (instancetype)initWithElementMap:(ASElementMap *)elementMap layout:(ASLayout *)layout +{ + NSMapTable *attrsMap = [NSMapTable mapTableWithKeyOptions:(NSMapTableObjectPointerPersonality | NSMapTableWeakMemory) valueOptions:NSMapTableStrongMemory]; + for (ASLayout *sublayout in layout.sublayouts) { + ASCollectionElement *element = ((ASCellNode *)sublayout.layoutElement).collectionElement; + NSIndexPath *indexPath = [elementMap indexPathForElement:element]; + NSString *supplementaryElementKind = element.supplementaryElementKind; + + UICollectionViewLayoutAttributes *attrs; + if (supplementaryElementKind == nil) { + attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]; + } else { + attrs = [UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:supplementaryElementKind withIndexPath:indexPath]; + } + + attrs.frame = sublayout.frame; + [attrsMap setObject:attrs forKey:element]; + } + + return [self initWithElementMap:elementMap contentSize:layout.size elementToLayoutArrtibutesMap:attrsMap]; +} + - (instancetype)initWithElementMap:(ASElementMap *)elementMap contentSize:(CGSize)contentSize elementToLayoutArrtibutesMap:(NSMapTable *)attrsMap { self = [super init]; diff --git a/Source/Private/ASTwoDimensionalArrayUtils.m b/Source/Private/ASTwoDimensionalArrayUtils.m index 7580582c3f..163f0b66bd 100644 --- a/Source/Private/ASTwoDimensionalArrayUtils.m +++ b/Source/Private/ASTwoDimensionalArrayUtils.m @@ -21,9 +21,10 @@ NSMutableArray *ASTwoDimensionalArrayDeepMutableCopy(NSArray *array) { NSMutableArray *newArray = [NSMutableArray arrayWithCapacity:array.count]; + NSInteger i = 0; for (NSArray *subarray in array) { ASDisplayNodeCAssert([subarray isKindOfClass:[NSArray class]], @"This function expects NSArray *"); - [newArray addObject:[subarray mutableCopy]]; + newArray[i++] = [subarray mutableCopy]; } return newArray; } @@ -65,11 +66,12 @@ void ASDeleteElementsInTwoDimensionalArrayAtIndexPaths(NSMutableArray *mutableAr { NSMutableArray *result = [NSMutableArray array]; NSInteger section = 0; + NSInteger i = 0; for (NSArray *subarray in twoDimensionalArray) { ASDisplayNodeCAssert([subarray isKindOfClass:[NSArray class]], @"This function expects NSArray *"); NSInteger itemCount = subarray.count; for (NSInteger item = 0; item < itemCount; item++) { - [result addObject:[NSIndexPath indexPathForItem:item inSection:section]]; + result[i++] = [NSIndexPath indexPathForItem:item inSection:section]; } section++; } @@ -79,10 +81,11 @@ void ASDeleteElementsInTwoDimensionalArrayAtIndexPaths(NSMutableArray *mutableAr NSArray *ASElementsInTwoDimensionalArray(NSArray * twoDimensionalArray) { NSMutableArray *result = [NSMutableArray array]; + NSInteger i = 0; for (NSArray *subarray in twoDimensionalArray) { ASDisplayNodeCAssert([subarray isKindOfClass:[NSArray class]], @"This function expects NSArray *"); for (id element in subarray) { - [result addObject:element]; + result[i++] = element; } } return result;