* Renamed range update callbacks
We finally settled on
didEnter/ExitDisplayState
didEnter/ExitPreloadState
didEnter/ExitVisibleState
This change is meant to unify the range update methods to relate to each
other and hopefully be a bit more self explanatory.
* Guarantee interface callbacks happen on main.
* move fetchData / clearFetchedData to default implementations
* Move deprecated methods to new deprecated category
* Don't bring in cocoapod change.
* Nits
* Capetalize
* Fixes a deadlock caused by walking up the heirarchy.
* Use scope locker / unlocker and add a comment.
* Add comment about calling __setNeedsLayout without the lock.
* Add default fade in / out layout transition
* Add example for layout transition
* Update for recent layout transition API changes
* To be able to do a layoutTransition the node needs to be loaded
* Rename layoutTransitionDuration to defaultLayoutTransitionDuration
* Expose default layout transition duration delay and options
* Use `UIViewAnimationOptionBeginFromCurrentState` for initial defaultLayoutTransitionOptions
The pending layout transition needs to stay alive at least until applySubnodeInsertions did finish execute as it can happen that with Implicit Hierarchy Management new nodes gonna be added that internally call setNeedsLayout what will invalidate and deallocate the transition in the middle of inserting nodes
* Revert "Revert "[ASLayoutSpec] Use childrenMap directly to prevent creating an NSArray within ASDK (#1937)""
This reverts commit 735b4ebd0872483044d98a5d05b43324e76fc8d4.
* Fix crash and add exception for mutating while using fast enumeration of ASLayoutSpec children
NSFastEnumeration is potentially quite dangerous in the wrong hands. In particular, it does not provide a safe mechanism for you to return temporary objects directly, and it does not provide any guarantee that you will be called when the enumeration has completed; therefore if we generate temporaries and store them in an instance variable, we will not necessarily be able to clean them up! This means fast enumeration methods should never be called within an autorelease pool or the autorelease pool be drained within the fast enumeration loop.
The reason is we store references to objects in the stackBuf struct by casting the child pointer to __autoreleasing id. If we pop the autorelease pool between calls to -countByEnumeratingWithState:objects:count:, it will die in a messy explosion of pointer dereferences and EXC_BAD_ACCESS.
* Add tests for ASDisplayNode and ASLayoutSpec fast enumeration
If a node was added to a supernode, the supernode could be in a layout pending state. All of the hierarchy state properties related to the transition need to be copied over as well as propagated down the subtree. This is especially important as with Implicit Hierarchy Management adding subnodes can happen while a transition is in fly
Something interesting going on here with ARC / Objective-C++ that we are investigating and will re-land.
This reverts commit c90ed08d1073701e2c7f8a2677d460c140f05264.
* [ASDisplayNode] Ensure that nil can never be returned from -measureWithSizeRange:
This can happen in rare cases when multiple relayouts occur while a transition is being measured.
* [ASDisplayNode] Use ternary operator style for nil check.
* Use childrenMap directly to prevent creating an NSArray in ASDK for ASLayoutSpec children
* Add locking for parent property in ASLayoutSpec
* Remove unnecessary import
* Add newline
* Add NSFastEnumeration to ASEnvironment and ASDisplayNode / ASLayoutSpec
* Change NSMutableArray initializer to arrayWithCapacity:
* Move ASLayoutSpec+Private.h into Private folder
Fixes building with Swift
* Remove lock for ASLayoutSpec parent
* Simplify applying layout transition in preparation for bigger layout transition API work
* Change from apply to complete in if layout transitions are involved and _applyLayout: to _setCalculatedLayout: for layout
* Change to applySubnodeInsertions and applySubnodeRemovals
* Change from completeTransition to commitTransition and flip logic around when to trampoline to the main thread for implicit hierarchy management
* More internal API improvements
* Fix merge conflicts
* Rename _layout to _calculatedLayout
* [ASEnvironmentTraitCollection] default user interface idiom to ASEnvironmentTraitCollection
UIUserInterfaceIdiomUnspecified is -1 so we were actually defaulting our trait collection to UIUserInterfaceIdiomPhone (which is 0).
* Fix a few places where we weren’t using the default method to create the base traits
[_ASHierarchyChangeSet] Oopsy daisy
[ASDataController] Tweak our update validation
[ASHierarchyChangeSet] Fix bugs
Finish up some stuff
[ASDataController] Put some stuff back
[ASChangeSetDataController] Always use changeset
[ASDataController] Put other stuff back
[_ASHierarchyChangeSet] Use fast enumeration
[_ASHierarchyChangeSet] Fix assertion format strings, return on fail so we don't crash in production
[ASDataController] Store data source item counts as vector rather than NSArray
[ASDataController] Build some tests for the update validation
[ASDataController] Fix issues with update validation
Get rid of new file
[ASDataController] Suppress changeset validation before initial reload
[ASDataController] Make invalid update log vs. exception publicly toggleable
* [ASDisplayNode] Short circuit measure calls that have a zero-area constrainedSize.
// If the constrainedSize is completely zero-area, then there is no possibility for layout calculations to be successful.
// This also avoids the issue of an inset being applied to 0, creating negative frame values.
* [ASDisplayNode] Fix to shouldMeasure change.
* One more fix.
* Add automatic measurement before layout
* Remove code not needed or addressed in a different PR
* Adjust comments and rename __layoutSublayouts to __layoutSubnodes
* Check before setting up a placeholder layer if the node should have a placeholder
* Always layout nodes on a background thread
* Remove semaphore in ASDataController for allocating nodes and layout
* Fix variable not used error
* Remove overhead to create subarray of contexts of nodes while layout nodes
* Remove extra allocation of allocatedNodes and indexPaths array
This situation is relatively uncommon. If a user manually uses -[UIView addSubnode:], the convenience category method,
and then calls -[ASDisplayNode removeFromSuperview] -- we would bypass performing the actual removal as no supernode pointer
is set. After further consideration, the special handling here to support divergence between the supernode pointer and
the view / layer hierarchy is not something we need to maintain going forward, and removing it makes addressing this easy.
Currently measurement always needs to happen on the main thread if implicit hierarchy management is enabled as adding and removing from nodes needs to happen on the main thread. We now will trampoline to the main thread to do the insertion and deletion of nodes.
This also resolves the issue that can occur if a node is already loaded deep in the layout hierarchy in the layout that the node is transforming to. Before insertion or deletion is happening we need to crawl the layout hierarchy to check that though.
I looked into the internals of UIImageView a bit. I would recommend to not fixing this in a universal way. UIImageView is specifically optimized for performance and does not use the usual way to provide the contents of the CALayer that backs the UIImageView.
Furthermore we cannot trigger a recreation of the contents of the UIImageView layer as if it get’s cleared and we call setNeedsDisplay on it it goes trough the normal flow to assign the contents to a layer via the CALayerDelegate methods. Unfortunately UIImageView does not do it, it actually does not implement some of the methods at all, so nothing will show up. It’s getting better, by calling setNeedsDisplay on an UIImageView layer it actually clears the contents and nothing is visible anymore. So we have to be careful to not calling that too.
Unfortunately I didn’t find a way yet to trigger a recreation of the UIImageView layers content except calling the private _updateState method.
That said it’s different for layers of other UIKit components like UILabel for example. Clearing the contents of a UILabel layer and calling setNeedsDisplay on the layer usually recreates the contents of the it and it will show up again.
This commit prevents to clear the contents of a layer for all wrapped UIKit and instead only NOT clear the content if the node wraps a UIImageView otherwise we should clear the contents of the layer to reclaim memory as usual.