diff --git a/AsyncDisplayKit.xcodeproj/project.pbxproj b/AsyncDisplayKit.xcodeproj/project.pbxproj index 525f24b3ad..73889b0026 100644 --- a/AsyncDisplayKit.xcodeproj/project.pbxproj +++ b/AsyncDisplayKit.xcodeproj/project.pbxproj @@ -589,8 +589,8 @@ E55D86331CA8A14000A0C26F /* ASLayoutable.mm in Sources */ = {isa = PBXBuildFile; fileRef = E55D86311CA8A14000A0C26F /* ASLayoutable.mm */; }; E5711A2B1C840C81009619D4 /* ASIndexedNodeContext.h in Headers */ = {isa = PBXBuildFile; fileRef = E5711A2A1C840C81009619D4 /* ASIndexedNodeContext.h */; settings = {ATTRIBUTES = (Public, ); }; }; E5711A2C1C840C81009619D4 /* ASIndexedNodeContext.h in Headers */ = {isa = PBXBuildFile; fileRef = E5711A2A1C840C81009619D4 /* ASIndexedNodeContext.h */; }; - E5711A2E1C840C96009619D4 /* ASIndexedNodeContext.m in Sources */ = {isa = PBXBuildFile; fileRef = E5711A2D1C840C96009619D4 /* ASIndexedNodeContext.m */; }; - E5711A301C840C96009619D4 /* ASIndexedNodeContext.m in Sources */ = {isa = PBXBuildFile; fileRef = E5711A2D1C840C96009619D4 /* ASIndexedNodeContext.m */; }; + E5711A2E1C840C96009619D4 /* ASIndexedNodeContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = E5711A2D1C840C96009619D4 /* ASIndexedNodeContext.mm */; }; + E5711A301C840C96009619D4 /* ASIndexedNodeContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = E5711A2D1C840C96009619D4 /* ASIndexedNodeContext.mm */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -955,7 +955,7 @@ E52405B41C8FEF16004DC8E7 /* ASLayoutTransition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASLayoutTransition.h; sourceTree = ""; }; E55D86311CA8A14000A0C26F /* ASLayoutable.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASLayoutable.mm; path = AsyncDisplayKit/Layout/ASLayoutable.mm; sourceTree = ""; }; E5711A2A1C840C81009619D4 /* ASIndexedNodeContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASIndexedNodeContext.h; sourceTree = ""; }; - E5711A2D1C840C96009619D4 /* ASIndexedNodeContext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASIndexedNodeContext.m; sourceTree = ""; }; + E5711A2D1C840C96009619D4 /* ASIndexedNodeContext.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASIndexedNodeContext.mm; sourceTree = ""; }; EFA731F0396842FF8AB635EE /* libPods-AsyncDisplayKitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AsyncDisplayKitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; FB07EABBCF28656C6297BC2D /* Pods-AsyncDisplayKitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AsyncDisplayKitTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AsyncDisplayKitTests/Pods-AsyncDisplayKitTests.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -1417,7 +1417,7 @@ AC026B671BD57D6F00BBC17E /* ASChangeSetDataController.h */, AC026B681BD57D6F00BBC17E /* ASChangeSetDataController.m */, E5711A2A1C840C81009619D4 /* ASIndexedNodeContext.h */, - E5711A2D1C840C96009619D4 /* ASIndexedNodeContext.m */, + E5711A2D1C840C96009619D4 /* ASIndexedNodeContext.mm */, ); name = "Data Controller"; sourceTree = ""; @@ -2114,7 +2114,7 @@ 205F0E121B371BD7007741D0 /* ASScrollDirection.m in Sources */, 9C8898BB1C738B9800D6B02E /* ASTextKitFontSizeAdjuster.mm in Sources */, D785F6631A74327E00291744 /* ASScrollNode.m in Sources */, - E5711A2E1C840C96009619D4 /* ASIndexedNodeContext.m in Sources */, + E5711A2E1C840C96009619D4 /* ASIndexedNodeContext.mm in Sources */, 058D0A2C195D050800B7D73C /* ASSentinel.m in Sources */, 9C8221971BA237B80037F19A /* ASStackBaselinePositionedLayout.mm in Sources */, 251B8EF81BBB3D690087C538 /* ASCollectionDataController.mm in Sources */, @@ -2242,7 +2242,7 @@ 69E100701CA89CB600D88C1B /* ASEnvironmentInternal.mm in Sources */, 254C6B891BF94F8A003EC431 /* ASTextKitRenderer+Positioning.mm in Sources */, 68355B341CB579B9001D4E68 /* ASImageNode+AnimatedImage.mm in Sources */, - E5711A301C840C96009619D4 /* ASIndexedNodeContext.m in Sources */, + E5711A301C840C96009619D4 /* ASIndexedNodeContext.mm in Sources */, B35062511B010EFD0018CF92 /* ASDisplayNode+UIViewBridge.mm in Sources */, B35061FC1B010EFD0018CF92 /* ASDisplayNode.mm in Sources */, B35061FF1B010EFD0018CF92 /* ASDisplayNodeExtras.mm in Sources */, diff --git a/AsyncDisplayKit/ASCollectionNode.mm b/AsyncDisplayKit/ASCollectionNode.mm index e5c7880f48..a29ee08cf2 100644 --- a/AsyncDisplayKit/ASCollectionNode.mm +++ b/AsyncDisplayKit/ASCollectionNode.mm @@ -11,6 +11,7 @@ #import "ASCollectionViewLayoutFacilitatorProtocol.h" #import "ASDisplayNode+Subclasses.h" #import "ASEnvironmentInternal.h" +#import "ASInternalHelpers.h" #import "ASRangeControllerUpdateRangeProtocol+Beta.h" #include diff --git a/AsyncDisplayKit/ASDisplayNode.mm b/AsyncDisplayKit/ASDisplayNode.mm index bd4e4c349a..d855c1780f 100644 --- a/AsyncDisplayKit/ASDisplayNode.mm +++ b/AsyncDisplayKit/ASDisplayNode.mm @@ -1252,7 +1252,7 @@ static bool disableNotificationsForMovingBetweenParents(ASDisplayNode *from, ASD // This call will apply our .hierarchyState to the new subnode. // If we are a managed hierarchy, as in ASCellNode trees, it will also apply our .interfaceState. [subnode __setSupernode:self]; - + if (self.nodeLoaded) { // If this node has a view or layer, force the subnode to also create its view or layer and add it to the hierarchy here. // Otherwise there is no way for the subnode's view or layer to enter the hierarchy, except recursing down all @@ -1298,7 +1298,7 @@ static bool disableNotificationsForMovingBetweenParents(ASDisplayNode *from, ASD _subnodes = [[NSMutableArray alloc] init]; [_subnodes insertObject:subnode atIndex:subnodeIndex]; [subnode __setSupernode:self]; - + // Don't bother inserting the view/layer if in a rasterized subtree, because there are no layers in the hierarchy and none of this could possibly work. if (!_flags.shouldRasterizeDescendants && [self __shouldLoadViewOrLayer]) { if (_layer) { @@ -1740,6 +1740,9 @@ static NSInteger incrementIfFound(NSInteger i) { [self exitHierarchyState:stateToEnterOrExit]; } + + // now that we have a supernode, propagate its traits to self. + ASEnvironmentStatePropagateDown(self, [newSupernode environmentTraitCollection]); } } @@ -1902,6 +1905,7 @@ void recursivelyTriggerDisplayForLayer(CALayer *layer, BOOL shouldBlock) if ((_methodOverrides & ASDisplayNodeMethodOverrideLayoutSpecThatFits) || _layoutSpecBlock != NULL) { ASLayoutSpec *layoutSpec = [self layoutSpecThatFits:constrainedSize]; layoutSpec.parent = self; // This causes upward propogation of any non-default layoutable values. + layoutSpec.traitCollection = self.asyncTraitCollection; layoutSpec.isMutable = NO; ASLayout *layout = [layoutSpec measureWithSizeRange:constrainedSize]; // Make sure layoutableObject of the root layout is `self`, so that the flattened layout will be structurally correct. @@ -2722,7 +2726,12 @@ static const char *ASDisplayNodeDrawingPriorityKey = "ASDrawingPriority"; - (ASEnvironmentTraitCollection)environmentTraitCollection { - return _environmentState.traitCollection; + return _environmentState.environmentTraitCollection; +} + +- (void)setEnvironmentTraitCollection:(ASEnvironmentTraitCollection)environmentTraitCollection +{ + _environmentState.environmentTraitCollection = environmentTraitCollection; } ASEnvironmentLayoutOptionsForwarding @@ -2731,7 +2740,7 @@ ASEnvironmentLayoutExtensibilityForwarding - (ASTraitCollection *)asyncTraitCollection { ASDN::MutexLocker l(_propertyLock); - return [ASTraitCollection traitCollectionWithASEnvironmentTraitCollection:_environmentState.traitCollection]; + return [ASTraitCollection traitCollectionWithASEnvironmentTraitCollection:self.environmentTraitCollection]; } #if TARGET_OS_TV diff --git a/AsyncDisplayKit/ASTableNode.mm b/AsyncDisplayKit/ASTableNode.mm index 7b413bc588..1642478d2d 100644 --- a/AsyncDisplayKit/ASTableNode.mm +++ b/AsyncDisplayKit/ASTableNode.mm @@ -7,10 +7,11 @@ // #import "ASEnvironmentInternal.h" -#import "ASFlowLayoutController.h" -#import "ASTableViewInternal.h" #import "ASDisplayNode+Subclasses.h" +#import "ASFlowLayoutController.h" +#import "ASInternalHelpers.h" #import "ASRangeControllerUpdateRangeProtocol+Beta.h" +#import "ASTableViewInternal.h" @interface _ASTablePendingState : NSObject @property (weak, nonatomic) id delegate; diff --git a/AsyncDisplayKit/ASViewController.h b/AsyncDisplayKit/ASViewController.h index 71a7e4a70c..123669b5c5 100644 --- a/AsyncDisplayKit/ASViewController.h +++ b/AsyncDisplayKit/ASViewController.h @@ -33,7 +33,7 @@ typedef ASTraitCollection * _Nonnull (^ASDisplayTraitsForTraitWindowSizeBlock)(C * ASVC keeps a strong reference to the context to make sure that it stays alive. If you change this value * it will propagate the change to the subnodes. */ -@property (nonatomic, strong) id _Nullable traitColectionContext; +@property (nonatomic, strong) id _Nullable traitCollectionContext; /** * Set this block to customize the ASDisplayTraits returned when the VC transitions to the given traitCollection. diff --git a/AsyncDisplayKit/ASViewController.mm b/AsyncDisplayKit/ASViewController.mm index 710016ccef..14f71850a5 100644 --- a/AsyncDisplayKit/ASViewController.mm +++ b/AsyncDisplayKit/ASViewController.mm @@ -8,6 +8,7 @@ #import "ASViewController.h" #import "ASAssert.h" +#import "ASAvailability.h" #import "ASDimension.h" #import "ASDisplayNodeInternal.h" #import "ASDisplayNode+FrameworkPrivate.h" @@ -55,12 +56,12 @@ - (void)dealloc { - if (_traitColectionContext != nil) { + if (_traitCollectionContext != nil) { // The setter will iterate through the VC's subnodes and replace the traitCollectionContext in their ASEnvironmentTraitCollection with nil. // Since the VC holds the only strong reference to this context and we are in the process of destroying // the VC, all the references in the subnodes will be unsafe unless we nil them out. More than likely all the subnodes will be dealloc'ed // as part of the VC being dealloc'ed, but this is just to make extra sure. - self.traitColectionContext = nil; + self.traitCollectionContext = nil; } } @@ -82,6 +83,13 @@ _node.frame = frame; _node.autoresizingMask = autoresizingMask; self.view = view; + + // ensure that self.node has a valid trait collection before a subclass's implementation of viewDidLoad. + // Any subnodes added in viewDidLoad will then inherit the proper environment. + if (AS_AT_LEAST_IOS8) { + ASEnvironmentTraitCollection traitCollection = [self environmentTraitCollectionForUITraitCollection:self.traitCollection]; + [self progagateNewEnvironmentTraitCollection:traitCollection]; + } } - (void)viewWillLayoutSubviews @@ -187,52 +195,53 @@ ASVisibilityDepthImplementation; #pragma mark - ASEnvironmentTraitCollection -- (void)setTraitColectionContext:(id)traitColectionContext +- (void)setTraitCollectionContext:(id)traitCollectionContext { - if (_traitColectionContext != traitColectionContext) { - // propagate first so that nodes aren't hanging around with a dealloc'ed pointer - ASEnvironmentTraitCollectionUpdateDisplayContext(self.node, traitColectionContext); + if (_traitCollectionContext != traitCollectionContext) { + // nil out the displayContext in the subnodes so they aren't hanging around with a dealloc'ed pointer don't set + // the new context yet as this will cause ASEnvironmentTraitCollectionIsEqualToASEnvironmentTraitCollection to fail + ASEnvironmentTraitCollectionUpdateDisplayContext(self.node, nil); - _traitColectionContext = traitColectionContext; + _traitCollectionContext = traitCollectionContext; } } -- (ASEnvironmentTraitCollection)displayTraitsForTraitCollection:(UITraitCollection *)traitCollection +- (ASEnvironmentTraitCollection)environmentTraitCollectionForUITraitCollection:(UITraitCollection *)traitCollection { if (self.overrideDisplayTraitsWithTraitCollection) { ASTraitCollection *asyncTraitCollection = self.overrideDisplayTraitsWithTraitCollection(traitCollection); - self.traitColectionContext = asyncTraitCollection.traitCollectionContext; + self.traitCollectionContext = asyncTraitCollection.traitCollectionContext; return [asyncTraitCollection environmentTraitCollection]; } ASEnvironmentTraitCollection asyncTraitCollection = ASEnvironmentTraitCollectionFromUITraitCollection(traitCollection); - asyncTraitCollection.displayContext = self.traitColectionContext; + asyncTraitCollection.displayContext = self.traitCollectionContext; return asyncTraitCollection; } -- (ASEnvironmentTraitCollection)displayTraitsForWindowSize:(CGSize)windowSize +- (ASEnvironmentTraitCollection)environmentTraitCollectionForWindowSize:(CGSize)windowSize { if (self.overrideDisplayTraitsWithWindowSize) { ASTraitCollection *traitCollection = self.overrideDisplayTraitsWithWindowSize(windowSize); - self.traitColectionContext = traitCollection.traitCollectionContext; + self.traitCollectionContext = traitCollection.traitCollectionContext; return [traitCollection environmentTraitCollection]; } return self.node.environmentTraitCollection; } -- (void)progagateNewDisplayTraits:(ASEnvironmentTraitCollection)traitCollection +- (void)progagateNewEnvironmentTraitCollection:(ASEnvironmentTraitCollection)environmentTraitCollection { ASEnvironmentState environmentState = self.node.environmentState; - ASEnvironmentTraitCollection oldTraitCollection = environmentState.traitCollection; + ASEnvironmentTraitCollection oldEnvironmentTraitCollection = environmentState.environmentTraitCollection; - if (ASEnvironmentTraitCollectionIsEqualToASEnvironmentTraitCollection(traitCollection, oldTraitCollection) == NO) { - environmentState.traitCollection = traitCollection; + if (ASEnvironmentTraitCollectionIsEqualToASEnvironmentTraitCollection(environmentTraitCollection, oldEnvironmentTraitCollection) == NO) { + environmentState.environmentTraitCollection = environmentTraitCollection; self.node.environmentState = environmentState; [self.node setNeedsLayout]; NSArray> *children = [self.node children]; for (id child in children) { - ASEnvironmentStatePropagateDown(child, environmentState.traitCollection); + ASEnvironmentStatePropagateDown(child, environmentState.environmentTraitCollection); } } } @@ -241,24 +250,24 @@ ASVisibilityDepthImplementation; { [super traitCollectionDidChange:previousTraitCollection]; - ASEnvironmentTraitCollection traitCollection = [self displayTraitsForTraitCollection:self.traitCollection]; - [self progagateNewDisplayTraits:traitCollection]; + ASEnvironmentTraitCollection environmentTraitCollection = [self environmentTraitCollectionForUITraitCollection:self.traitCollection]; + [self progagateNewEnvironmentTraitCollection:environmentTraitCollection]; } - (void)willTransitionToTraitCollection:(UITraitCollection *)newCollection withTransitionCoordinator:(id)coordinator { [super willTransitionToTraitCollection:newCollection withTransitionCoordinator:coordinator]; - ASEnvironmentTraitCollection traitCollection = [self displayTraitsForTraitCollection:newCollection]; - [self progagateNewDisplayTraits:traitCollection]; + ASEnvironmentTraitCollection environmentTraitCollection = [self environmentTraitCollectionForUITraitCollection:newCollection]; + [self progagateNewEnvironmentTraitCollection:environmentTraitCollection]; } - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator { [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; - ASEnvironmentTraitCollection traitCollection = [self displayTraitsForWindowSize:size]; - [self progagateNewDisplayTraits:traitCollection]; + ASEnvironmentTraitCollection environmentTraitCollection = [self environmentTraitCollectionForWindowSize:size]; + [self progagateNewEnvironmentTraitCollection:environmentTraitCollection]; } @end diff --git a/AsyncDisplayKit/Details/ASCollectionDataController.mm b/AsyncDisplayKit/Details/ASCollectionDataController.mm index ba1647a282..3a51eed154 100644 --- a/AsyncDisplayKit/Details/ASCollectionDataController.mm +++ b/AsyncDisplayKit/Details/ASCollectionDataController.mm @@ -158,6 +158,9 @@ - (void)_populateSupplementaryNodesOfKind:(NSString *)kind withMutableContexts:(NSMutableArray *)contexts { + id environment = [self.environmentDelegate dataControllerEnvironment]; + ASEnvironmentTraitCollection environmentTraitCollection = environment.environmentTraitCollection; + NSUInteger sectionCount = [self.collectionDataSource dataController:self numberOfSectionsForSupplementaryNodeOfKind:kind]; for (NSUInteger i = 0; i < sectionCount; i++) { NSIndexPath *sectionIndexPath = [[NSIndexPath alloc] initWithIndex:i]; @@ -176,7 +179,8 @@ ASSizeRange constrainedSize = [self constrainedSizeForNodeOfKind:kind atIndexPath:indexPath]; ASIndexedNodeContext *context = [[ASIndexedNodeContext alloc] initWithNodeBlock:supplementaryCellBlock indexPath:indexPath - constrainedSize:constrainedSize]; + constrainedSize:constrainedSize + environmentTraitCollection:environmentTraitCollection]; [contexts addObject:context]; } } @@ -184,6 +188,9 @@ - (void)_populateSupplementaryNodesOfKind:(NSString *)kind withSections:(NSIndexSet *)sections mutableContexts:(NSMutableArray *)contexts { + id environment = [self.environmentDelegate dataControllerEnvironment]; + ASEnvironmentTraitCollection environmentTraitCollection = environment.environmentTraitCollection; + [sections enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) { NSUInteger rowNum = [self.collectionDataSource dataController:self supplementaryNodesOfKind:kind inSection:idx]; NSIndexPath *sectionIndex = [[NSIndexPath alloc] initWithIndex:idx]; @@ -201,7 +208,8 @@ ASSizeRange constrainedSize = [self constrainedSizeForNodeOfKind:kind atIndexPath:indexPath]; ASIndexedNodeContext *context = [[ASIndexedNodeContext alloc] initWithNodeBlock:supplementaryCellBlock indexPath:indexPath - constrainedSize:constrainedSize]; + constrainedSize:constrainedSize + environmentTraitCollection:environmentTraitCollection]; [contexts addObject:context]; } }]; diff --git a/AsyncDisplayKit/Details/ASDataController.mm b/AsyncDisplayKit/Details/ASDataController.mm index 611dd1c5d3..44719f8652 100644 --- a/AsyncDisplayKit/Details/ASDataController.mm +++ b/AsyncDisplayKit/Details/ASDataController.mm @@ -519,6 +519,9 @@ static void *kASSizingQueueContext = &kASSizingQueueContext; */ - (NSArray *)_populateFromDataSourceWithSectionIndexSet:(NSIndexSet *)indexSet { + id environment = [self.environmentDelegate dataControllerEnvironment]; + ASEnvironmentTraitCollection environmentTraitCollection = environment.environmentTraitCollection; + NSMutableArray *contexts = [NSMutableArray array]; [indexSet enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) { NSUInteger rowNum = [_dataSource dataController:self rowsInSection:idx]; @@ -527,18 +530,11 @@ static void *kASSizingQueueContext = &kASSizingQueueContext; NSIndexPath *indexPath = [sectionIndex indexPathByAddingIndex:i]; ASCellNodeBlock nodeBlock = [_dataSource dataController:self nodeBlockAtIndexPath:indexPath]; - // When creating a node, make sure to pass along the current display traits so it will be laid out properly - ASCellNodeBlock nodeBlockPropagatingDisplayTraits = ^{ - ASCellNode *cellNode = nodeBlock(); - id environment = [self.environmentDelegate dataControllerEnvironment]; - ASEnvironmentStatePropagateDown(cellNode, [environment environmentTraitCollection]); - return cellNode; - }; - ASSizeRange constrainedSize = [self constrainedSizeForNodeOfKind:ASDataControllerRowNodeKind atIndexPath:indexPath]; - [contexts addObject:[[ASIndexedNodeContext alloc] initWithNodeBlock:nodeBlockPropagatingDisplayTraits + [contexts addObject:[[ASIndexedNodeContext alloc] initWithNodeBlock:nodeBlock indexPath:indexPath - constrainedSize:constrainedSize]]; + constrainedSize:constrainedSize + environmentTraitCollection:environmentTraitCollection]]; } }]; return contexts; @@ -791,12 +787,16 @@ static void *kASSizingQueueContext = &kASSizingQueueContext; NSMutableArray *contexts = [[NSMutableArray alloc] initWithCapacity:indexPaths.count]; [self accessDataSourceWithBlock:^{ + id environment = [self.environmentDelegate dataControllerEnvironment]; + ASEnvironmentTraitCollection environmentTraitCollection = environment.environmentTraitCollection; + for (NSIndexPath *indexPath in sortedIndexPaths) { ASCellNodeBlock nodeBlock = [_dataSource dataController:self nodeBlockAtIndexPath:indexPath]; ASSizeRange constrainedSize = [self constrainedSizeForNodeOfKind:ASDataControllerRowNodeKind atIndexPath:indexPath]; [contexts addObject:[[ASIndexedNodeContext alloc] initWithNodeBlock:nodeBlock indexPath:indexPath - constrainedSize:constrainedSize]]; + constrainedSize:constrainedSize + environmentTraitCollection:environmentTraitCollection]]; } [_editingTransactionQueue addOperationWithBlock:^{ @@ -842,12 +842,16 @@ static void *kASSizingQueueContext = &kASSizingQueueContext; // FIXME: Shouldn't deletes be sorted in descending order? [indexPaths sortedArrayUsingSelector:@selector(compare:)]; + id environment = [self.environmentDelegate dataControllerEnvironment]; + ASEnvironmentTraitCollection environmentTraitCollection = environment.environmentTraitCollection; + for (NSIndexPath *indexPath in indexPaths) { ASCellNodeBlock nodeBlock = [_dataSource dataController:self nodeBlockAtIndexPath:indexPath]; ASSizeRange constrainedSize = [self constrainedSizeForNodeOfKind:ASDataControllerRowNodeKind atIndexPath:indexPath]; [contexts addObject:[[ASIndexedNodeContext alloc] initWithNodeBlock:nodeBlock indexPath:indexPath - constrainedSize:constrainedSize]]; + constrainedSize:constrainedSize + environmentTraitCollection:environmentTraitCollection]]; } [_editingTransactionQueue addOperationWithBlock:^{ diff --git a/AsyncDisplayKit/Details/ASEnvironment.h b/AsyncDisplayKit/Details/ASEnvironment.h index 580c4a64d3..16b71a9b65 100644 --- a/AsyncDisplayKit/Details/ASEnvironment.h +++ b/AsyncDisplayKit/Details/ASEnvironment.h @@ -97,7 +97,7 @@ extern BOOL ASEnvironmentTraitCollectionIsEqualToASEnvironmentTraitCollection(AS typedef struct ASEnvironmentState { struct ASEnvironmentHierarchyState hierarchyState; struct ASEnvironmentLayoutOptionsState layoutOptionsState; - struct ASEnvironmentTraitCollection traitCollection; + struct ASEnvironmentTraitCollection environmentTraitCollection; } ASEnvironmentState; extern ASEnvironmentState ASEnvironmentStateMakeDefault(); @@ -137,6 +137,8 @@ ASDISPLAYNODE_EXTERN_C_END /// convenience method. Users should access the trait collections through the NSObject based asyncTraitCollection API - (ASEnvironmentTraitCollection)environmentTraitCollection; +/// sets a trait collection on this environment state. +- (void)setEnvironmentTraitCollection:(ASEnvironmentTraitCollection)environmentTraitCollection; @end // ASCollection/TableNodes don't actually have ASCellNodes as subnodes. Because of this we can't rely on display trait @@ -150,17 +152,19 @@ ASDISPLAYNODE_EXTERN_C_END - (void)setEnvironmentState:(ASEnvironmentState)environmentState\ {\ ASDN::MutexLocker l(lock);\ - ASEnvironmentTraitCollection oldTraits = self.environmentState.traitCollection;\ + ASEnvironmentTraitCollection oldTraits = self.environmentState.environmentTraitCollection;\ [super setEnvironmentState:environmentState];\ - ASEnvironmentTraitCollection currentTraits = environmentState.traitCollection;\ + ASEnvironmentTraitCollection currentTraits = environmentState.environmentTraitCollection;\ if (ASEnvironmentTraitCollectionIsEqualToASEnvironmentTraitCollection(currentTraits, oldTraits) == NO) {\ - NSArray *> *completedNodes = [self.view.dataController completedNodes];\ - for (NSArray *sectionArray in completedNodes) {\ - for (ASCellNode *cellNode in sectionArray) {\ - ASEnvironmentStatePropagateDown(cellNode, currentTraits);\ - [cellNode setNeedsLayout];\ + ASPerformBlockOnMainThread(^{\ + NSArray *> *completedNodes = [self.view.dataController completedNodes];\ + for (NSArray *sectionArray in completedNodes) {\ + for (ASCellNode *cellNode in sectionArray) {\ + ASEnvironmentStatePropagateDown(cellNode, currentTraits);\ + [cellNode setNeedsLayout];\ + }\ }\ - }\ + });\ }\ }\ diff --git a/AsyncDisplayKit/Details/ASEnvironment.mm b/AsyncDisplayKit/Details/ASEnvironment.mm index b1e17e95fa..be7c627c20 100644 --- a/AsyncDisplayKit/Details/ASEnvironment.mm +++ b/AsyncDisplayKit/Details/ASEnvironment.mm @@ -29,13 +29,13 @@ ASEnvironmentHierarchyState _ASEnvironmentHierarchyStateMakeDefault() extern void ASEnvironmentTraitCollectionUpdateDisplayContext(id rootEnvironment, id context) { ASEnvironmentState envState = [rootEnvironment environmentState]; - ASEnvironmentTraitCollection displayTraits = envState.traitCollection; - displayTraits.displayContext = context; - envState.traitCollection = displayTraits; + ASEnvironmentTraitCollection environmentTraitCollection = envState.environmentTraitCollection; + environmentTraitCollection.displayContext = context; + envState.environmentTraitCollection = environmentTraitCollection; [rootEnvironment setEnvironmentState:envState]; for (id child in [rootEnvironment children]) { - ASEnvironmentStatePropagateDown(child, displayTraits); + ASEnvironmentStatePropagateDown(child, environmentTraitCollection); } } @@ -77,7 +77,7 @@ ASEnvironmentState ASEnvironmentStateMakeDefault() return (ASEnvironmentState) { .layoutOptionsState = _ASEnvironmentLayoutOptionsStateMakeDefault(), .hierarchyState = _ASEnvironmentHierarchyStateMakeDefault(), - .traitCollection = _ASEnvironmentTraitCollectionMakeDefault() + .environmentTraitCollection = _ASEnvironmentTraitCollectionMakeDefault() }; } diff --git a/AsyncDisplayKit/Details/ASIndexedNodeContext.h b/AsyncDisplayKit/Details/ASIndexedNodeContext.h index ed1d2f49ba..0dd90d51c1 100644 --- a/AsyncDisplayKit/Details/ASIndexedNodeContext.h +++ b/AsyncDisplayKit/Details/ASIndexedNodeContext.h @@ -7,15 +7,18 @@ // #import +#import @interface ASIndexedNodeContext : NSObject @property (nonatomic, readonly, strong) NSIndexPath *indexPath; @property (nonatomic, readonly, assign) ASSizeRange constrainedSize; +@property (nonatomic, readonly, assign) ASEnvironmentTraitCollection environmentTraitCollection; - (instancetype)initWithNodeBlock:(ASCellNodeBlock)nodeBlock indexPath:(NSIndexPath *)indexPath - constrainedSize:(ASSizeRange)constrainedSize; + constrainedSize:(ASSizeRange)constrainedSize + environmentTraitCollection:(ASEnvironmentTraitCollection)environmentTraitCollection; /** * Returns a node allocated by executing node block. Node block will be nil out immediately. diff --git a/AsyncDisplayKit/Details/ASIndexedNodeContext.m b/AsyncDisplayKit/Details/ASIndexedNodeContext.mm similarity index 74% rename from AsyncDisplayKit/Details/ASIndexedNodeContext.m rename to AsyncDisplayKit/Details/ASIndexedNodeContext.mm index b6038137d6..e296a84a4c 100644 --- a/AsyncDisplayKit/Details/ASIndexedNodeContext.m +++ b/AsyncDisplayKit/Details/ASIndexedNodeContext.mm @@ -7,6 +7,8 @@ // #import "ASIndexedNodeContext.h" +#import "ASEnvironmentInternal.h" +#import "ASCellNode.h" @interface ASIndexedNodeContext () @@ -19,7 +21,8 @@ - (instancetype)initWithNodeBlock:(ASCellNodeBlock)nodeBlock indexPath:(NSIndexPath *)indexPath - constrainedSize:(ASSizeRange)constrainedSize; + constrainedSize:(ASSizeRange)constrainedSize + environmentTraitCollection:(ASEnvironmentTraitCollection)environmentTraitCollection { NSAssert(nodeBlock != nil && indexPath != nil, @"Node block and index path must not be nil"); self = [super init]; @@ -27,6 +30,7 @@ _nodeBlock = nodeBlock; _indexPath = indexPath; _constrainedSize = constrainedSize; + _environmentTraitCollection = environmentTraitCollection; } return self; } @@ -36,6 +40,7 @@ NSAssert(_nodeBlock != nil, @"Node block is gone. Should not execute it more than once"); ASCellNode *node = _nodeBlock(); _nodeBlock = nil; + ASEnvironmentStatePropagateDown(node, _environmentTraitCollection); return node; } diff --git a/AsyncDisplayKit/Details/ASTraitCollection.h b/AsyncDisplayKit/Details/ASTraitCollection.h index 2168a40302..e9b99ef4fd 100644 --- a/AsyncDisplayKit/Details/ASTraitCollection.h +++ b/AsyncDisplayKit/Details/ASTraitCollection.h @@ -28,7 +28,7 @@ * Be aware that internally this context is held by a C struct which cannot retain the pointer. * ASTraitCollection is generally a very short-lived class, existing only to provide a non-struct API * to trait collections. When an ASTraitCollection is returned via one of ASViewController's 2 - * custom trait collection creation blocks, traitColectionContext is assigned to the VC's traitColectionContext. + * custom trait collection creation blocks, traitCollectionContext is assigned to the VC's traitCollectionContext. * This makes sure that the VC is the owner of the context and ASEnvironmentTraitCollections will not * have a reference to a dangling pointer. */ @@ -50,5 +50,6 @@ - (ASEnvironmentTraitCollection)environmentTraitCollection; +- (BOOL)isEqualToTraitCollection:(ASTraitCollection *)traitCollection; @end diff --git a/AsyncDisplayKit/Details/ASTraitCollection.m b/AsyncDisplayKit/Details/ASTraitCollection.m index af492c759f..d424c2effa 100644 --- a/AsyncDisplayKit/Details/ASTraitCollection.m +++ b/AsyncDisplayKit/Details/ASTraitCollection.m @@ -95,4 +95,14 @@ }; } +- (BOOL)isEqualToTraitCollection:(ASTraitCollection *)traitCollection +{ + return self.displayScale == traitCollection.displayScale && + self.horizontalSizeClass == traitCollection.horizontalSizeClass && + self.verticalSizeClass == traitCollection.verticalSizeClass && + self.userInterfaceIdiom == traitCollection.userInterfaceIdiom && + self.traitCollectionContext == traitCollection.traitCollectionContext && + self.forceTouchCapability == traitCollection.forceTouchCapability; +} + @end diff --git a/AsyncDisplayKit/Layout/ASBackgroundLayoutSpec.mm b/AsyncDisplayKit/Layout/ASBackgroundLayoutSpec.mm index bbeac0b882..ea18aca990 100644 --- a/AsyncDisplayKit/Layout/ASBackgroundLayoutSpec.mm +++ b/AsyncDisplayKit/Layout/ASBackgroundLayoutSpec.mm @@ -68,15 +68,4 @@ static NSString * const kBackgroundChildKey = @"kBackgroundChildKey"; return [super childForIdentifier:kBackgroundChildKey]; } -- (void)setChildren:(NSArray *)children -{ - ASDisplayNodeAssert(NO, @"not supported by this layout spec"); -} - -- (NSArray *)children -{ - ASDisplayNodeAssert(NO, @"not supported by this layout spec"); - return nil; -} - @end diff --git a/AsyncDisplayKit/Layout/ASInsetLayoutSpec.mm b/AsyncDisplayKit/Layout/ASInsetLayoutSpec.mm index ce7e6b4ea9..5c03393be7 100644 --- a/AsyncDisplayKit/Layout/ASInsetLayoutSpec.mm +++ b/AsyncDisplayKit/Layout/ASInsetLayoutSpec.mm @@ -115,15 +115,4 @@ static CGFloat centerInset(CGFloat outer, CGFloat inner) return [ASLayout layoutWithLayoutableObject:self size:computedSize sublayouts:@[sublayout]]; } -- (void)setChildren:(NSArray *)children -{ - ASDisplayNodeAssert(NO, @"not supported by this layout spec"); -} - -- (NSArray *)children -{ - ASDisplayNodeAssert(NO, @"not supported by this layout spec"); - return nil; -} - @end diff --git a/AsyncDisplayKit/Layout/ASLayoutSpec.h b/AsyncDisplayKit/Layout/ASLayoutSpec.h index 02a6d4f035..3f7a9586d6 100644 --- a/AsyncDisplayKit/Layout/ASLayoutSpec.h +++ b/AsyncDisplayKit/Layout/ASLayoutSpec.h @@ -11,6 +11,8 @@ #import #import +@class ASTraitCollection; + NS_ASSUME_NONNULL_BEGIN /** A layout spec is an immutable object that describes a layout, loosely inspired by React. */ @@ -23,6 +25,8 @@ NS_ASSUME_NONNULL_BEGIN */ @property (nonatomic, assign) BOOL isMutable; +@property (nonatomic, strong, nullable) ASTraitCollection *traitCollection; + - (instancetype)init; /** diff --git a/AsyncDisplayKit/Layout/ASLayoutSpec.mm b/AsyncDisplayKit/Layout/ASLayoutSpec.mm index 8932e27555..af46b53842 100644 --- a/AsyncDisplayKit/Layout/ASLayoutSpec.mm +++ b/AsyncDisplayKit/Layout/ASLayoutSpec.mm @@ -26,7 +26,6 @@ ASEnvironmentState _environmentState; ASDN::RecursiveMutex _propertyLock; - id _child; NSArray *_children; NSMutableDictionary *_childrenWithIdentifier; } @@ -45,7 +44,7 @@ } _isMutable = YES; _environmentState = ASEnvironmentStateMakeDefault(); - + _children = [NSArray array]; return self; } @@ -113,28 +112,46 @@ } } -- (void)setChild:(id)child; +- (void)setChild:(id)child { ASDisplayNodeAssert(self.isMutable, @"Cannot set properties when layout spec is not mutable"); - - id finalLayoutable = [self layoutableToAddFromLayoutable:child]; - _child = finalLayoutable; - [self propagateUpLayoutable:finalLayoutable]; + if (child) { + id finalLayoutable = [self layoutableToAddFromLayoutable:child]; + if (finalLayoutable) { + _children = @[finalLayoutable]; + [self propagateUpLayoutable:finalLayoutable]; + } + } else { + // remove the only child + _children = [NSArray array]; + } } - (void)setChild:(id)child forIdentifier:(NSString *)identifier { ASDisplayNodeAssert(self.isMutable, @"Cannot set properties when layout spec is not mutable"); - - id finalLayoutable = [self layoutableToAddFromLayoutable:child]; - self.childrenWithIdentifier[identifier] = finalLayoutable; + if (child) { + id finalLayoutable = [self layoutableToAddFromLayoutable:child]; + self.childrenWithIdentifier[identifier] = finalLayoutable; + if (finalLayoutable) { + _children = [_children arrayByAddingObject:finalLayoutable]; + } + } else { + id oldChild = self.childrenWithIdentifier[identifier]; + if (oldChild) { + self.childrenWithIdentifier[identifier] = nil; + NSMutableArray *mutableChildren = [_children mutableCopy]; + [mutableChildren removeObject:oldChild]; + _children = [mutableChildren copy]; + } + } // TODO: Should we propagate up the layoutable at it could happen that multiple children will propagated up their // layout options and one child will overwrite values from another child // [self propagateUpLayoutable:finalLayoutable]; } -- (void)setChildren:(NSArray *)children +- (void)setChildren:(NSArray> *)children { ASDisplayNodeAssert(self.isMutable, @"Cannot set properties when layout spec is not mutable"); @@ -146,6 +163,8 @@ _children = nil; if (finalChildren.size() > 0) { _children = [NSArray arrayWithObjects:&finalChildren[0] count:finalChildren.size()]; + } else { + _children = [NSArray array]; } } @@ -156,14 +175,21 @@ - (id)child { - return _child; + return [_children firstObject]; } - (NSArray *)children { - return [_children copy]; + return _children; } +- (void)setTraitCollection:(ASTraitCollection *)traitCollection +{ + if ([traitCollection isEqualToTraitCollection:self.traitCollection] == NO) { + _traitCollection = traitCollection; + ASEnvironmentStatePropagateDown(self, [traitCollection environmentTraitCollection]); + } +} #pragma mark - ASEnvironment @@ -201,7 +227,12 @@ - (ASEnvironmentTraitCollection)environmentTraitCollection { - return _environmentState.traitCollection; + return _environmentState.environmentTraitCollection; +} + +- (void)setEnvironmentTraitCollection:(ASEnvironmentTraitCollection)environmentTraitCollection +{ + _environmentState.environmentTraitCollection = environmentTraitCollection; } ASEnvironmentLayoutOptionsForwarding @@ -210,7 +241,7 @@ ASEnvironmentLayoutExtensibilityForwarding - (ASTraitCollection *)asyncTraitCollection { ASDN::MutexLocker l(_propertyLock); - return [ASTraitCollection traitCollectionWithASEnvironmentTraitCollection:_environmentState.traitCollection]; + return [ASTraitCollection traitCollectionWithASEnvironmentTraitCollection:self.environmentTraitCollection]; } @end diff --git a/AsyncDisplayKit/Layout/ASOverlayLayoutSpec.mm b/AsyncDisplayKit/Layout/ASOverlayLayoutSpec.mm index ba580d08b1..892872179e 100644 --- a/AsyncDisplayKit/Layout/ASOverlayLayoutSpec.mm +++ b/AsyncDisplayKit/Layout/ASOverlayLayoutSpec.mm @@ -61,17 +61,6 @@ static NSString * const kOverlayChildKey = @"kOverlayChildKey"; return [ASLayout layoutWithLayoutableObject:self size:contentsLayout.size sublayouts:sublayouts]; } -- (void)setChildren:(NSArray *)children -{ - ASDisplayNodeAssert(NO, @"not supported by this layout spec"); -} - -- (NSArray *)children -{ - ASDisplayNodeAssert(NO, @"not supported by this layout spec"); - return nil; -} - @end @implementation ASOverlayLayoutSpec (Debugging) diff --git a/AsyncDisplayKit/Layout/ASRatioLayoutSpec.mm b/AsyncDisplayKit/Layout/ASRatioLayoutSpec.mm index 4e04d4ca05..4e9c66ed98 100644 --- a/AsyncDisplayKit/Layout/ASRatioLayoutSpec.mm +++ b/AsyncDisplayKit/Layout/ASRatioLayoutSpec.mm @@ -75,17 +75,6 @@ return [ASLayout layoutWithLayoutableObject:self size:sublayout.size sublayouts:@[sublayout]]; } -- (void)setChildren:(NSArray *)children -{ - ASDisplayNodeAssert(NO, @"not supported by this layout spec"); -} - -- (NSArray *)children -{ - ASDisplayNodeAssert(NO, @"not supported by this layout spec"); - return nil; -} - @end @implementation ASRatioLayoutSpec (Debugging) diff --git a/AsyncDisplayKit/Layout/ASRelativeLayoutSpec.mm b/AsyncDisplayKit/Layout/ASRelativeLayoutSpec.mm index 7a1a0ea5e0..4206171b5e 100644 --- a/AsyncDisplayKit/Layout/ASRelativeLayoutSpec.mm +++ b/AsyncDisplayKit/Layout/ASRelativeLayoutSpec.mm @@ -92,17 +92,6 @@ return [ASLayout layoutWithLayoutableObject:self size:size sublayouts:@[sublayout]]; } -- (void)setChildren:(NSArray *)children -{ - ASDisplayNodeAssert(NO, @"not supported by this layout spec"); -} - -- (NSArray *)children -{ - ASDisplayNodeAssert(NO, @"not supported by this layout spec"); - return nil; -} - - (CGFloat)proportionOfAxisForAxisPosition:(ASRelativeLayoutSpecPosition)position { if ((position & ASRelativeLayoutSpecPositionCenter) != 0) { diff --git a/AsyncDisplayKit/Layout/ASStackLayoutSpec.mm b/AsyncDisplayKit/Layout/ASStackLayoutSpec.mm index 26b6d449c7..cb99f38288 100644 --- a/AsyncDisplayKit/Layout/ASStackLayoutSpec.mm +++ b/AsyncDisplayKit/Layout/ASStackLayoutSpec.mm @@ -121,17 +121,6 @@ _baselineRelativeArrangement = baselineRelativeArrangement; } -- (void)setChild:(id)child forIdentifier:(NSString *)identifier -{ - ASDisplayNodeAssert(NO, @"ASStackLayoutSpec only supports setChildren"); -} - -- (id)childForIdentifier:(NSString *)identifier -{ - ASDisplayNodeAssert(NO, @"ASStackLayoutSpec only supports children"); - return nil; -} - - (ASLayout *)measureWithSizeRange:(ASSizeRange)constrainedSize { if (self.children.count == 0) { diff --git a/AsyncDisplayKit/Layout/ASStaticLayoutSpec.mm b/AsyncDisplayKit/Layout/ASStaticLayoutSpec.mm index a727376a57..68db47ff14 100644 --- a/AsyncDisplayKit/Layout/ASStaticLayoutSpec.mm +++ b/AsyncDisplayKit/Layout/ASStaticLayoutSpec.mm @@ -72,17 +72,6 @@ sublayouts:sublayouts]; } -- (void)setChild:(id)child forIdentifier:(NSString *)identifier -{ - ASDisplayNodeAssert(NO, @"ASStaticLayoutSpec only supports setChildren"); -} - -- (id)childForIdentifier:(NSString *)identifier -{ - ASDisplayNodeAssert(NO, @"ASStaticLayoutSpec only supports children"); - return nil; -} - @end @implementation ASStaticLayoutSpec (ASEnvironment) diff --git a/AsyncDisplayKit/Private/ASEnvironmentInternal.h b/AsyncDisplayKit/Private/ASEnvironmentInternal.h index 30d62670e7..7a7b363e67 100644 --- a/AsyncDisplayKit/Private/ASEnvironmentInternal.h +++ b/AsyncDisplayKit/Private/ASEnvironmentInternal.h @@ -58,14 +58,14 @@ ASEnvironmentState ASEnvironmentMergeObjectAndState(ASEnvironmentState environme template void ASEnvironmentStatePropagateDown(id object, ASEnvironmentStateType state) { ASEnvironmentPerformBlockOnObjectAndChildren(object, ^(id node) { - object.environmentState = ASEnvironmentMergeObjectAndState(object.environmentState, state, ASEnvironmentStatePropagation::DOWN); + node.environmentState = ASEnvironmentMergeObjectAndState(node.environmentState, state, ASEnvironmentStatePropagation::DOWN); }); } template void ASEnvironmentStatePropagateUp(id object, ASEnvironmentStateType state) { ASEnvironmentPerformBlockOnObjectAndParents(object, ^(id node) { - object.environmentState = ASEnvironmentMergeObjectAndState(object.environmentState, state, ASEnvironmentStatePropagation::UP); + node.environmentState = ASEnvironmentMergeObjectAndState(node.environmentState, state, ASEnvironmentStatePropagation::UP); }); } diff --git a/AsyncDisplayKit/Private/ASEnvironmentInternal.mm b/AsyncDisplayKit/Private/ASEnvironmentInternal.mm index e74e0abf60..af856b970d 100644 --- a/AsyncDisplayKit/Private/ASEnvironmentInternal.mm +++ b/AsyncDisplayKit/Private/ASEnvironmentInternal.mm @@ -201,14 +201,14 @@ ASEnvironmentState ASEnvironmentMergeObjectAndState(ASEnvironmentState childEnvi // Support propagate down if (propagation == ASEnvironmentStatePropagation::DOWN) { - ASEnvironmentTraitCollection childTraitCollection = childEnvironmentState.traitCollection; + ASEnvironmentTraitCollection childTraitCollection = childEnvironmentState.environmentTraitCollection; childTraitCollection.horizontalSizeClass = parentTraitCollection.horizontalSizeClass; childTraitCollection.verticalSizeClass = parentTraitCollection.verticalSizeClass; childTraitCollection.userInterfaceIdiom = parentTraitCollection.userInterfaceIdiom; childTraitCollection.forceTouchCapability = parentTraitCollection.forceTouchCapability; childTraitCollection.displayScale = parentTraitCollection.displayScale; childTraitCollection.displayContext = parentTraitCollection.displayContext; - childEnvironmentState.traitCollection = childTraitCollection; + childEnvironmentState.environmentTraitCollection = childTraitCollection; } return childEnvironmentState; diff --git a/examples_extra/ASTraitCollection/Podfile b/examples_extra/ASTraitCollection/Podfile index 6c012e3c04..919de4b311 100644 --- a/examples_extra/ASTraitCollection/Podfile +++ b/examples_extra/ASTraitCollection/Podfile @@ -1,3 +1,5 @@ source 'https://github.com/CocoaPods/Specs.git' -platform :ios, '8.0' -pod 'AsyncDisplayKit', :path => '../..' +platform :ios, '7.0' +target 'Sample' do + pod 'AsyncDisplayKit', :path => '../..' +end diff --git a/examples_extra/ASTraitCollection/Sample.xcodeproj/project.pbxproj b/examples_extra/ASTraitCollection/Sample.xcodeproj/project.pbxproj index b46865ed75..f9e679bb36 100644 --- a/examples_extra/ASTraitCollection/Sample.xcodeproj/project.pbxproj +++ b/examples_extra/ASTraitCollection/Sample.xcodeproj/project.pbxproj @@ -10,7 +10,7 @@ 05E2128719D4DB510098F589 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 05E2128619D4DB510098F589 /* main.m */; }; 05E2128A19D4DB510098F589 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 05E2128919D4DB510098F589 /* AppDelegate.m */; }; 05E2128D19D4DB510098F589 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 05E2128C19D4DB510098F589 /* ViewController.m */; }; - 3EC0CDCBA10D483D9F386E5E /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D24B17D1E4A4E7A9566C5E9 /* libPods.a */; }; + 1BEECAB53F4B61DCB949ED44 /* libPods-Sample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1EEDFC574739077BA65E0CF5 /* libPods-Sample.a */; }; 9C37D01E1CC94BC9004C8BC1 /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9C37D01D1CC94BC9004C8BC1 /* Launch Screen.storyboard */; }; 9CACC7811CCEAF9E009A1613 /* TableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CACC7801CCEAF9E009A1613 /* TableViewController.m */; }; 9CACC7841CCEAFAE009A1613 /* CollectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CACC7831CCEAFAE009A1613 /* CollectionViewController.m */; }; @@ -19,6 +19,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 056298286C03B7760575CC56 /* Pods-Sample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Sample.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Sample/Pods-Sample.debug.xcconfig"; sourceTree = ""; }; 05E2128119D4DB510098F589 /* Sample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Sample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 05E2128519D4DB510098F589 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 05E2128619D4DB510098F589 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; @@ -27,6 +28,7 @@ 05E2128B19D4DB510098F589 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 05E2128C19D4DB510098F589 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 088AA6578212BE9BFBB07B70 /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = ""; }; + 1EEDFC574739077BA65E0CF5 /* libPods-Sample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Sample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 3D24B17D1E4A4E7A9566C5E9 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; 9C37D01D1CC94BC9004C8BC1 /* Launch Screen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = "Launch Screen.storyboard"; sourceTree = ""; }; 9CACC77F1CCEAF9E009A1613 /* TableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TableViewController.h; sourceTree = ""; }; @@ -37,6 +39,7 @@ 9CACC7861CCEBD3B009A1613 /* KittenNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KittenNode.m; sourceTree = ""; }; 9CACC7881CCEC82C009A1613 /* OverrideViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OverrideViewController.h; sourceTree = ""; }; 9CACC7891CCEC82C009A1613 /* OverrideViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OverrideViewController.m; sourceTree = ""; }; + A7F0013FBBCBEA0C9FB68986 /* Pods-Sample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Sample.release.xcconfig"; path = "Pods/Target Support Files/Pods-Sample/Pods-Sample.release.xcconfig"; sourceTree = ""; }; C068F1D3F0CC317E895FCDAB /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -45,7 +48,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 3EC0CDCBA10D483D9F386E5E /* libPods.a in Frameworks */, + 1BEECAB53F4B61DCB949ED44 /* libPods-Sample.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -107,6 +110,7 @@ isa = PBXGroup; children = ( 3D24B17D1E4A4E7A9566C5E9 /* libPods.a */, + 1EEDFC574739077BA65E0CF5 /* libPods-Sample.a */, ); name = Frameworks; sourceTree = ""; @@ -116,6 +120,8 @@ children = ( C068F1D3F0CC317E895FCDAB /* Pods.debug.xcconfig */, 088AA6578212BE9BFBB07B70 /* Pods.release.xcconfig */, + 056298286C03B7760575CC56 /* Pods-Sample.debug.xcconfig */, + A7F0013FBBCBEA0C9FB68986 /* Pods-Sample.release.xcconfig */, ); name = Pods; sourceTree = ""; @@ -127,12 +133,12 @@ isa = PBXNativeTarget; buildConfigurationList = 05E212A419D4DB510098F589 /* Build configuration list for PBXNativeTarget "Sample" */; buildPhases = ( - E080B80F89C34A25B3488E26 /* Check Pods Manifest.lock */, + E080B80F89C34A25B3488E26 /* 📦 Check Pods Manifest.lock */, 05E2127D19D4DB510098F589 /* Sources */, 05E2127E19D4DB510098F589 /* Frameworks */, 05E2127F19D4DB510098F589 /* Resources */, - F012A6F39E0149F18F564F50 /* Copy Pods Resources */, - FFF65E837E66ADA71296F0FF /* Embed Pods Frameworks */, + F012A6F39E0149F18F564F50 /* 📦 Copy Pods Resources */, + FFF65E837E66ADA71296F0FF /* 📦 Embed Pods Frameworks */, ); buildRules = ( ); @@ -187,14 +193,14 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - E080B80F89C34A25B3488E26 /* Check Pods Manifest.lock */ = { + E080B80F89C34A25B3488E26 /* 📦 Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); - name = "Check Pods Manifest.lock"; + name = "📦 Check Pods Manifest.lock"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; @@ -202,34 +208,34 @@ shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; showEnvVarsInLog = 0; }; - F012A6F39E0149F18F564F50 /* Copy Pods Resources */ = { + F012A6F39E0149F18F564F50 /* 📦 Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); - name = "Copy Pods Resources"; + name = "📦 Copy Pods Resources"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n"; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Sample/Pods-Sample-resources.sh\"\n"; showEnvVarsInLog = 0; }; - FFF65E837E66ADA71296F0FF /* Embed Pods Frameworks */ = { + FFF65E837E66ADA71296F0FF /* 📦 Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); - name = "Embed Pods Frameworks"; + name = "📦 Embed Pods Frameworks"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-frameworks.sh\"\n"; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Sample/Pods-Sample-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ @@ -330,7 +336,7 @@ }; 05E212A519D4DB510098F589 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = C068F1D3F0CC317E895FCDAB /* Pods.debug.xcconfig */; + baseConfigurationReference = 056298286C03B7760575CC56 /* Pods-Sample.debug.xcconfig */; buildSettings = { INFOPLIST_FILE = Sample/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; @@ -342,7 +348,7 @@ }; 05E212A619D4DB510098F589 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 088AA6578212BE9BFBB07B70 /* Pods.release.xcconfig */; + baseConfigurationReference = A7F0013FBBCBEA0C9FB68986 /* Pods-Sample.release.xcconfig */; buildSettings = { INFOPLIST_FILE = Sample/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; diff --git a/examples_extra/ASTraitCollection/Sample/KittenNode.m b/examples_extra/ASTraitCollection/Sample/KittenNode.m index 98771a8cb8..18babcdc36 100644 --- a/examples_extra/ASTraitCollection/Sample/KittenNode.m +++ b/examples_extra/ASTraitCollection/Sample/KittenNode.m @@ -130,13 +130,11 @@ static const CGFloat kInnerPadding = 10.0f; - (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize { - ASTraitCollection *traitCollection = [self asyncTraitCollection]; - ASStackLayoutSpec *stackSpec = [[ASStackLayoutSpec alloc] init]; stackSpec.spacing = kInnerPadding; - stackSpec.children = @[_imageNode, _textNode]; + [stackSpec setChildren:@[_imageNode, _textNode]]; - if (traitCollection.horizontalSizeClass == UIUserInterfaceSizeClassRegular) { + if (self.asyncTraitCollection.horizontalSizeClass == UIUserInterfaceSizeClassRegular) { _imageNode.alignSelf = ASStackLayoutAlignSelfStart; stackSpec.direction = ASStackLayoutDirectionHorizontal; } else {