mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-16 19:30:29 +00:00
Adds support for having multiple interface state delegates. (#979)
* Adds support for having multiple interface state delegates. Hopefully in a performant way. * Switch to respondsToSelector for int del instead of separate object * Add CHANGELOG * Make ASDisplayNode+InterfaceState.h public * Huy's comments * Don't even bother removing since it's a weak hash table.
This commit is contained in:
parent
f0dac14505
commit
a4f78ad3e0
@ -115,6 +115,7 @@
|
||||
68355B3E1CB57A60001D4E68 /* ASPINRemoteImageDownloader.m in Sources */ = {isa = PBXBuildFile; fileRef = 68355B361CB57A5A001D4E68 /* ASPINRemoteImageDownloader.m */; };
|
||||
68355B401CB57A69001D4E68 /* ASImageContainerProtocolCategories.m in Sources */ = {isa = PBXBuildFile; fileRef = 68355B381CB57A5A001D4E68 /* ASImageContainerProtocolCategories.m */; };
|
||||
68355B411CB57A6C001D4E68 /* ASImageContainerProtocolCategories.h in Headers */ = {isa = PBXBuildFile; fileRef = 68355B371CB57A5A001D4E68 /* ASImageContainerProtocolCategories.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
683F563720E409D700CEB7A3 /* ASDisplayNode+InterfaceState.h in Headers */ = {isa = PBXBuildFile; fileRef = 683F563620E409D600CEB7A3 /* ASDisplayNode+InterfaceState.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
68AF37DB1CBEF4D80077BF76 /* ASImageNode+AnimatedImagePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 68B8A4DB1CBD911D007E4543 /* ASImageNode+AnimatedImagePrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
68B0277B1C1A79D60041016B /* ASDisplayNode+Beta.h in Headers */ = {isa = PBXBuildFile; fileRef = 68B027791C1A79CC0041016B /* ASDisplayNode+Beta.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
68B8A4E21CBDB958007E4543 /* ASWeakProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 68B8A4DF1CBDB958007E4543 /* ASWeakProxy.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
@ -667,6 +668,7 @@
|
||||
68355B371CB57A5A001D4E68 /* ASImageContainerProtocolCategories.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASImageContainerProtocolCategories.h; sourceTree = "<group>"; };
|
||||
68355B381CB57A5A001D4E68 /* ASImageContainerProtocolCategories.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASImageContainerProtocolCategories.m; sourceTree = "<group>"; };
|
||||
68355B391CB57A5A001D4E68 /* ASPINRemoteImageDownloader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASPINRemoteImageDownloader.h; sourceTree = "<group>"; };
|
||||
683F563620E409D600CEB7A3 /* ASDisplayNode+InterfaceState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASDisplayNode+InterfaceState.h"; sourceTree = "<group>"; };
|
||||
68B027791C1A79CC0041016B /* ASDisplayNode+Beta.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASDisplayNode+Beta.h"; sourceTree = "<group>"; };
|
||||
68B8A4DB1CBD911D007E4543 /* ASImageNode+AnimatedImagePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASImageNode+AnimatedImagePrivate.h"; sourceTree = "<group>"; };
|
||||
68B8A4DF1CBDB958007E4543 /* ASWeakProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASWeakProxy.h; sourceTree = "<group>"; };
|
||||
@ -1156,6 +1158,7 @@
|
||||
68B027791C1A79CC0041016B /* ASDisplayNode+Beta.h */,
|
||||
CC034A071E60BEB400626263 /* ASDisplayNode+Convenience.h */,
|
||||
CC034A081E60BEB400626263 /* ASDisplayNode+Convenience.m */,
|
||||
683F563620E409D600CEB7A3 /* ASDisplayNode+InterfaceState.h */,
|
||||
69BCE3D71EC6513B007DCCAD /* ASDisplayNode+Layout.mm */,
|
||||
058D09DA195D050800B7D73C /* ASDisplayNode+Subclasses.h */,
|
||||
90FC784E1E4BFE1B00383C5A /* ASDisplayNode+Yoga.mm */,
|
||||
@ -1915,6 +1918,7 @@
|
||||
CC034A091E60BEB400626263 /* ASDisplayNode+Convenience.h in Headers */,
|
||||
254C6B7E1BF94DF4003EC431 /* ASTextKitTailTruncater.h in Headers */,
|
||||
B35062491B010EFD0018CF92 /* _ASCoreAnimationExtras.h in Headers */,
|
||||
683F563720E409D700CEB7A3 /* ASDisplayNode+InterfaceState.h in Headers */,
|
||||
68EE0DBE1C1B4ED300BA1B99 /* ASMainSerialQueue.h in Headers */,
|
||||
CCCCCCE11EC3EF060087FE10 /* ASTextUtilities.h in Headers */,
|
||||
B350624B1B010EFD0018CF92 /* _ASPendingState.h in Headers */,
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
## master
|
||||
* Add your own contributions to the next release on the line below this with your name.
|
||||
- [ASDisplayNode] Adds support for multiple interface state delegates. [Garrett Moon](https://github.com/garrettmoon) [#979](https://github.com/TextureGroup/Texture/pull/979)
|
||||
- [ASDataController] Add capability to renew supplementary views (update map) when size change from zero to non-zero.[Max Wang](https://github.com/wsdwsd0829) [#842](https://github.com/TextureGroup/Texture/pull/842)
|
||||
- Make `ASPerformMainThreadDeallocation` visible in C. [Adlai Holler](https://github.com/Adlai-Holler)
|
||||
- Add snapshot test for astextnode2. [Max Wang](https://github.com/wsdwsd0829) [#935](https://github.com/TextureGroup/Texture/pull/935)
|
||||
|
||||
124
Source/ASDisplayNode+InterfaceState.h
Normal file
124
Source/ASDisplayNode+InterfaceState.h
Normal file
@ -0,0 +1,124 @@
|
||||
//
|
||||
// ASDisplayNode+InterfaceState.h
|
||||
// Texture
|
||||
//
|
||||
// Copyright (c) 2017-present, Pinterest, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
/**
|
||||
* Interface state is available on ASDisplayNode and ASViewController, and
|
||||
* allows checking whether a node is in an interface situation where it is prudent to trigger certain
|
||||
* actions: measurement, data loading, display, and visibility (the latter for animations or other onscreen-only effects).
|
||||
*
|
||||
* The defualt state, ASInterfaceStateNone, means that the element is not predicted to be onscreen soon and
|
||||
* preloading should not be performed. Swift: use [] for the default behavior.
|
||||
*/
|
||||
typedef NS_OPTIONS(NSUInteger, ASInterfaceState)
|
||||
{
|
||||
/** The element is not predicted to be onscreen soon and preloading should not be performed */
|
||||
ASInterfaceStateNone = 0,
|
||||
/** The element may be added to a view soon that could become visible. Measure the layout, including size calculation. */
|
||||
ASInterfaceStateMeasureLayout = 1 << 0,
|
||||
/** The element is likely enough to come onscreen that disk and/or network data required for display should be fetched. */
|
||||
ASInterfaceStatePreload = 1 << 1,
|
||||
/** The element is very likely to become visible, and concurrent rendering should be executed for any -setNeedsDisplay. */
|
||||
ASInterfaceStateDisplay = 1 << 2,
|
||||
/** The element is physically onscreen by at least 1 pixel.
|
||||
In practice, all other bit fields should also be set when this flag is set. */
|
||||
ASInterfaceStateVisible = 1 << 3,
|
||||
|
||||
/**
|
||||
* The node is not contained in a cell but it is in a window.
|
||||
*
|
||||
* Currently we only set `interfaceState` to other values for
|
||||
* nodes contained in table views or collection views.
|
||||
*/
|
||||
ASInterfaceStateInHierarchy = ASInterfaceStateMeasureLayout | ASInterfaceStatePreload | ASInterfaceStateDisplay | ASInterfaceStateVisible,
|
||||
};
|
||||
|
||||
@protocol ASInterfaceStateDelegate <NSObject>
|
||||
@optional
|
||||
|
||||
/**
|
||||
* @abstract Called whenever any bit in the ASInterfaceState bitfield is changed.
|
||||
* @discussion Subclasses may use this to monitor when they become visible, should free cached data, and much more.
|
||||
* @see ASInterfaceState
|
||||
*/
|
||||
- (void)interfaceStateDidChange:(ASInterfaceState)newState fromState:(ASInterfaceState)oldState;
|
||||
|
||||
/**
|
||||
* @abstract Called whenever the node becomes visible.
|
||||
* @discussion Subclasses may use this to monitor when they become visible.
|
||||
* @note This method is guaranteed to be called on main.
|
||||
*/
|
||||
- (void)didEnterVisibleState;
|
||||
|
||||
/**
|
||||
* @abstract Called whenever the node is no longer visible.
|
||||
* @discussion Subclasses may use this to monitor when they are no longer visible.
|
||||
* @note This method is guaranteed to be called on main.
|
||||
*/
|
||||
- (void)didExitVisibleState;
|
||||
|
||||
/**
|
||||
* @abstract Called whenever the the node has entered the display state.
|
||||
* @discussion Subclasses may use this to monitor when a node should be rendering its content.
|
||||
* @note This method is guaranteed to be called on main.
|
||||
*/
|
||||
- (void)didEnterDisplayState;
|
||||
|
||||
/**
|
||||
* @abstract Called whenever the the node has exited the display state.
|
||||
* @discussion Subclasses may use this to monitor when a node should no longer be rendering its content.
|
||||
* @note This method is guaranteed to be called on main.
|
||||
*/
|
||||
- (void)didExitDisplayState;
|
||||
|
||||
/**
|
||||
* @abstract Called whenever the the node has entered the preload state.
|
||||
* @discussion Subclasses may use this to monitor data for a node should be preloaded, either from a local or remote source.
|
||||
* @note This method is guaranteed to be called on main.
|
||||
*/
|
||||
- (void)didEnterPreloadState;
|
||||
|
||||
/**
|
||||
* @abstract Called whenever the the node has exited the preload state.
|
||||
* @discussion Subclasses may use this to monitor whether preloading data for a node should be canceled.
|
||||
* @note This method is guaranteed to be called on main.
|
||||
*/
|
||||
- (void)didExitPreloadState;
|
||||
|
||||
/**
|
||||
* @abstract Called when the node has completed applying the layout.
|
||||
* @discussion Can be used for operations that are performed after layout has completed.
|
||||
* @note This method is guaranteed to be called on main.
|
||||
*/
|
||||
- (void)nodeDidLayout;
|
||||
|
||||
/**
|
||||
* @abstract Called when the node loads.
|
||||
* @discussion Can be used for operations that are performed after the node's view is available.
|
||||
* @note This method is guaranteed to be called on main.
|
||||
*/
|
||||
- (void)nodeDidLoad;
|
||||
|
||||
/**
|
||||
* @abstract Indicates that the receiver and all subnodes have finished displaying.
|
||||
* @discussion May be called more than once, for example if the receiver has a network image node.
|
||||
* This is called after the first display pass even if network image nodes have not downloaded anything
|
||||
* (text would be done, and other nodes that are ready to do their final display). Each render of
|
||||
* every progressive jpeg network node would cause this to be called, so this hook could be called up to
|
||||
* 1 + (pJPEGcount * pJPEGrenderCount) times. The render count depends on how many times the downloader calls
|
||||
* the progressImage block.
|
||||
* @note This method is guaranteed to be called on main.
|
||||
*/
|
||||
- (void)hierarchyDisplayDidFinish;
|
||||
|
||||
@end
|
||||
@ -42,74 +42,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
* variables.
|
||||
*/
|
||||
|
||||
@protocol ASInterfaceStateDelegate <NSObject>
|
||||
@required
|
||||
|
||||
/**
|
||||
* @abstract Called whenever any bit in the ASInterfaceState bitfield is changed.
|
||||
* @discussion Subclasses may use this to monitor when they become visible, should free cached data, and much more.
|
||||
* @see ASInterfaceState
|
||||
*/
|
||||
- (void)interfaceStateDidChange:(ASInterfaceState)newState fromState:(ASInterfaceState)oldState;
|
||||
|
||||
/**
|
||||
* @abstract Called whenever the node becomes visible.
|
||||
* @discussion Subclasses may use this to monitor when they become visible.
|
||||
* @note This method is guaranteed to be called on main.
|
||||
*/
|
||||
- (void)didEnterVisibleState;
|
||||
|
||||
/**
|
||||
* @abstract Called whenever the node is no longer visible.
|
||||
* @discussion Subclasses may use this to monitor when they are no longer visible.
|
||||
* @note This method is guaranteed to be called on main.
|
||||
*/
|
||||
- (void)didExitVisibleState;
|
||||
|
||||
/**
|
||||
* @abstract Called whenever the the node has entered the display state.
|
||||
* @discussion Subclasses may use this to monitor when a node should be rendering its content.
|
||||
* @note This method is guaranteed to be called on main.
|
||||
*/
|
||||
- (void)didEnterDisplayState;
|
||||
|
||||
/**
|
||||
* @abstract Called whenever the the node has exited the display state.
|
||||
* @discussion Subclasses may use this to monitor when a node should no longer be rendering its content.
|
||||
* @note This method is guaranteed to be called on main.
|
||||
*/
|
||||
- (void)didExitDisplayState;
|
||||
|
||||
/**
|
||||
* @abstract Called whenever the the node has entered the preload state.
|
||||
* @discussion Subclasses may use this to monitor data for a node should be preloaded, either from a local or remote source.
|
||||
* @note This method is guaranteed to be called on main.
|
||||
*/
|
||||
- (void)didEnterPreloadState;
|
||||
|
||||
/**
|
||||
* @abstract Called whenever the the node has exited the preload state.
|
||||
* @discussion Subclasses may use this to monitor whether preloading data for a node should be canceled.
|
||||
* @note This method is guaranteed to be called on main.
|
||||
*/
|
||||
- (void)didExitPreloadState;
|
||||
|
||||
/**
|
||||
* @abstract Called when the node has completed applying the layout.
|
||||
* @discussion Can be used for operations that are performed after layout has completed.
|
||||
* @note This method is guaranteed to be called on main.
|
||||
*/
|
||||
- (void)nodeDidLayout;
|
||||
|
||||
/**
|
||||
* @abstract Called when the node loads.
|
||||
* @discussion Can be used for operations that are performed after the node's view is available.
|
||||
* @note This method is guaranteed to be called on main.
|
||||
*/
|
||||
- (void)nodeDidLoad;
|
||||
|
||||
@end
|
||||
|
||||
@interface ASDisplayNode (Subclassing) <ASInterfaceStateDelegate>
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
#import <AsyncDisplayKit/_ASAsyncTransactionContainer.h>
|
||||
#import <AsyncDisplayKit/ASBaseDefines.h>
|
||||
#import <AsyncDisplayKit/ASDimension.h>
|
||||
#import <AsyncDisplayKit/ASDisplayNode+InterfaceState.h>
|
||||
#import <AsyncDisplayKit/ASAsciiArtBoxCreator.h>
|
||||
#import <AsyncDisplayKit/ASObjectDescriptionHelpers.h>
|
||||
#import <AsyncDisplayKit/ASLayoutElement.h>
|
||||
@ -70,37 +71,6 @@ typedef ASLayoutSpec * _Nonnull(^ASLayoutSpecBlock)(__kindof ASDisplayNode *node
|
||||
*/
|
||||
typedef void (^ASDisplayNodeNonFatalErrorBlock)(NSError *error);
|
||||
|
||||
/**
|
||||
* Interface state is available on ASDisplayNode and ASViewController, and
|
||||
* allows checking whether a node is in an interface situation where it is prudent to trigger certain
|
||||
* actions: measurement, data loading, display, and visibility (the latter for animations or other onscreen-only effects).
|
||||
*
|
||||
* The defualt state, ASInterfaceStateNone, means that the element is not predicted to be onscreen soon and
|
||||
* preloading should not be performed. Swift: use [] for the default behavior.
|
||||
*/
|
||||
typedef NS_OPTIONS(NSUInteger, ASInterfaceState)
|
||||
{
|
||||
/** The element is not predicted to be onscreen soon and preloading should not be performed */
|
||||
ASInterfaceStateNone = 0,
|
||||
/** The element may be added to a view soon that could become visible. Measure the layout, including size calculation. */
|
||||
ASInterfaceStateMeasureLayout = 1 << 0,
|
||||
/** The element is likely enough to come onscreen that disk and/or network data required for display should be fetched. */
|
||||
ASInterfaceStatePreload = 1 << 1,
|
||||
/** The element is very likely to become visible, and concurrent rendering should be executed for any -setNeedsDisplay. */
|
||||
ASInterfaceStateDisplay = 1 << 2,
|
||||
/** The element is physically onscreen by at least 1 pixel.
|
||||
In practice, all other bit fields should also be set when this flag is set. */
|
||||
ASInterfaceStateVisible = 1 << 3,
|
||||
|
||||
/**
|
||||
* The node is not contained in a cell but it is in a window.
|
||||
*
|
||||
* Currently we only set `interfaceState` to other values for
|
||||
* nodes contained in table views or collection views.
|
||||
*/
|
||||
ASInterfaceStateInHierarchy = ASInterfaceStateMeasureLayout | ASInterfaceStatePreload | ASInterfaceStateDisplay | ASInterfaceStateVisible,
|
||||
};
|
||||
|
||||
typedef NS_ENUM(NSInteger, ASCornerRoundingType) {
|
||||
ASCornerRoundingTypeDefaultSlowCALayer,
|
||||
ASCornerRoundingTypePrecomposited,
|
||||
@ -292,6 +262,24 @@ AS_EXTERN NSInteger const ASDefaultDrawingPriority;
|
||||
*/
|
||||
@property (readonly) ASInterfaceState interfaceState;
|
||||
|
||||
/**
|
||||
* @abstract Adds a delegate to receive notifications on interfaceState changes.
|
||||
*
|
||||
* @warning This must be called from the main thread.
|
||||
*
|
||||
* @see ASInterfaceState
|
||||
*/
|
||||
- (void)addInterfaceStateDelegate:(id <ASInterfaceStateDelegate>)interfaceStateDelegate;
|
||||
|
||||
/**
|
||||
* @abstract Removes a delegate from receiving notifications on interfaceState changes.
|
||||
*
|
||||
* @warning This must be called from the main thread.
|
||||
*
|
||||
* @see ASInterfaceState
|
||||
*/
|
||||
- (void)removeInterfaceStateDelegate:(id <ASInterfaceStateDelegate>)interfaceStateDelegate;
|
||||
|
||||
/**
|
||||
* @abstract Class property that allows to set a block that can be called on non-fatal errors. This
|
||||
* property can be useful for cases when Async Display Kit can recover from an abnormal behavior, but
|
||||
|
||||
@ -36,6 +36,7 @@
|
||||
#import <AsyncDisplayKit/ASDisplayNodeExtras.h>
|
||||
#import <AsyncDisplayKit/ASDisplayNodeInternal.h>
|
||||
#import <AsyncDisplayKit/ASDisplayNode+FrameworkPrivate.h>
|
||||
#import <AsyncDisplayKit/ASDisplayNode+InterfaceState.h>
|
||||
#import <AsyncDisplayKit/ASDisplayNode+Subclasses.h>
|
||||
#import <AsyncDisplayKit/ASEqualityHelpers.h>
|
||||
#import <AsyncDisplayKit/ASGraphicsContext.h>
|
||||
@ -71,7 +72,6 @@ NSInteger const ASDefaultDrawingPriority = ASDefaultTransactionPriority;
|
||||
@protocol CALayerDelegate;
|
||||
|
||||
@interface ASDisplayNode () <UIGestureRecognizerDelegate, CALayerDelegate, _ASDisplayLayerDelegate, ASCATransactionQueueObserving>
|
||||
|
||||
/**
|
||||
* See ASDisplayNodeInternal.h for ivars
|
||||
*/
|
||||
@ -544,7 +544,11 @@ ASSynthesizeLockingMethodsWithMutex(__instanceLock__);
|
||||
block(self);
|
||||
}
|
||||
|
||||
[_interfaceStateDelegate nodeDidLoad];
|
||||
for (id <ASInterfaceStateDelegate> delegate in _interfaceStateDelegates) {
|
||||
if ([delegate respondsToSelector:@selector(nodeDidLoad)]) {
|
||||
[delegate nodeDidLoad];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)didLoad
|
||||
@ -1225,7 +1229,11 @@ ASSynthesizeLockingMethodsWithMutex(__instanceLock__);
|
||||
ASDisplayNodeAssertMainThread();
|
||||
ASDisplayNodeAssertLockUnownedByCurrentThread(__instanceLock__);
|
||||
ASDisplayNodeAssertTrue(self.isNodeLoaded);
|
||||
[_interfaceStateDelegate nodeDidLayout];
|
||||
for (id <ASInterfaceStateDelegate> delegate in _interfaceStateDelegates) {
|
||||
if ([delegate respondsToSelector:@selector(nodeDidLayout)]) {
|
||||
[delegate nodeDidLayout];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark Layout Transition
|
||||
@ -1447,6 +1455,13 @@ NSString * const ASRenderingEngineDidDisplayNodesScheduledBeforeTimestamp = @"AS
|
||||
if (_pendingDisplayNodes.isEmpty) {
|
||||
|
||||
[self hierarchyDisplayDidFinish];
|
||||
|
||||
for (id <ASInterfaceStateDelegate> delegate in _interfaceStateDelegates) {
|
||||
if ([delegate respondsToSelector:@selector(hierarchyDisplayDidFinish)]) {
|
||||
[delegate hierarchyDisplayDidFinish];
|
||||
}
|
||||
}
|
||||
|
||||
BOOL placeholderShouldPersist = [self placeholderShouldPersist];
|
||||
|
||||
__instanceLock__.lock();
|
||||
@ -3142,7 +3157,12 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
|
||||
{
|
||||
// Subclass hook
|
||||
ASDisplayNodeAssertLockUnownedByCurrentThread(__instanceLock__);
|
||||
[_interfaceStateDelegate interfaceStateDidChange:newState fromState:oldState];
|
||||
ASDisplayNodeAssertMainThread();
|
||||
for (id <ASInterfaceStateDelegate> delegate in _interfaceStateDelegates) {
|
||||
if ([delegate respondsToSelector:@selector(interfaceStateDidChange:fromState:)]) {
|
||||
[delegate interfaceStateDidChange:newState fromState:oldState];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)shouldScheduleDisplayWithNewInterfaceState:(ASInterfaceState)newInterfaceState
|
||||
@ -3152,6 +3172,24 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
|
||||
return willDisplay && (willDisplay != nowDisplay);
|
||||
}
|
||||
|
||||
- (void)addInterfaceStateDelegate:(id <ASInterfaceStateDelegate>)interfaceStateDelegate
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
|
||||
// Not a fan of lazy loading, but this method won't get called very often and avoiding
|
||||
// the overhead of creating this is probably worth it.
|
||||
if (_interfaceStateDelegates == nil) {
|
||||
_interfaceStateDelegates = [NSHashTable weakObjectsHashTable];
|
||||
}
|
||||
[_interfaceStateDelegates addObject:interfaceStateDelegate];
|
||||
}
|
||||
|
||||
- (void)removeInterfaceStateDelegate:(id <ASInterfaceStateDelegate>)interfaceStateDelegate
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
[_interfaceStateDelegates removeObject:interfaceStateDelegate];
|
||||
}
|
||||
|
||||
- (BOOL)isVisible
|
||||
{
|
||||
ASDN::MutexLocker l(__instanceLock__);
|
||||
@ -3163,7 +3201,11 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
|
||||
// subclass override
|
||||
ASDisplayNodeAssertMainThread();
|
||||
ASDisplayNodeAssertLockUnownedByCurrentThread(__instanceLock__);
|
||||
[_interfaceStateDelegate didEnterVisibleState];
|
||||
for (id <ASInterfaceStateDelegate> delegate in _interfaceStateDelegates) {
|
||||
if ([delegate respondsToSelector:@selector(didEnterVisibleState)]) {
|
||||
[delegate didEnterVisibleState];
|
||||
}
|
||||
}
|
||||
#if AS_ENABLE_TIPS
|
||||
[ASTipsController.shared nodeDidAppear:self];
|
||||
#endif
|
||||
@ -3174,7 +3216,11 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
|
||||
// subclass override
|
||||
ASDisplayNodeAssertMainThread();
|
||||
ASDisplayNodeAssertLockUnownedByCurrentThread(__instanceLock__);
|
||||
[_interfaceStateDelegate didExitVisibleState];
|
||||
for (id <ASInterfaceStateDelegate> delegate in _interfaceStateDelegates) {
|
||||
if ([delegate respondsToSelector:@selector(didExitVisibleState)]) {
|
||||
[delegate didExitVisibleState];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)isInDisplayState
|
||||
@ -3188,7 +3234,11 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
|
||||
// subclass override
|
||||
ASDisplayNodeAssertMainThread();
|
||||
ASDisplayNodeAssertLockUnownedByCurrentThread(__instanceLock__);
|
||||
[_interfaceStateDelegate didEnterDisplayState];
|
||||
for (id <ASInterfaceStateDelegate> delegate in _interfaceStateDelegates) {
|
||||
if ([delegate respondsToSelector:@selector(didEnterDisplayState)]) {
|
||||
[delegate didEnterDisplayState];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)didExitDisplayState
|
||||
@ -3196,7 +3246,11 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
|
||||
// subclass override
|
||||
ASDisplayNodeAssertMainThread();
|
||||
ASDisplayNodeAssertLockUnownedByCurrentThread(__instanceLock__);
|
||||
[_interfaceStateDelegate didExitDisplayState];
|
||||
for (id <ASInterfaceStateDelegate> delegate in _interfaceStateDelegates) {
|
||||
if ([delegate respondsToSelector:@selector(didExitDisplayState)]) {
|
||||
[delegate didExitDisplayState];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)isInPreloadState
|
||||
@ -3247,14 +3301,22 @@ ASDISPLAYNODE_INLINE BOOL subtreeIsRasterized(ASDisplayNode *node) {
|
||||
[self layoutIfNeeded];
|
||||
}
|
||||
|
||||
[_interfaceStateDelegate didEnterPreloadState];
|
||||
for (id <ASInterfaceStateDelegate> delegate in _interfaceStateDelegates) {
|
||||
if ([delegate respondsToSelector:@selector(didEnterPreloadState)]) {
|
||||
[delegate didEnterPreloadState];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)didExitPreloadState
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
ASDisplayNodeAssertLockUnownedByCurrentThread(__instanceLock__);
|
||||
[_interfaceStateDelegate didExitPreloadState];
|
||||
for (id <ASInterfaceStateDelegate> delegate in _interfaceStateDelegates) {
|
||||
if ([delegate respondsToSelector:@selector(didExitPreloadState)]) {
|
||||
[delegate didExitPreloadState];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)clearContents
|
||||
|
||||
@ -15,9 +15,10 @@
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
|
||||
#import <AsyncDisplayKit/ASWeakProxy.h>
|
||||
#import <AsyncDisplayKit/ASNodeController+Beta.h>
|
||||
#import <AsyncDisplayKit/ASInternalHelpers.h>
|
||||
#import <AsyncDisplayKit/ASDisplayNode+FrameworkPrivate.h>
|
||||
#import <AsyncDisplayKit/ASNodeController+Beta.h>
|
||||
#import <AsyncDisplayKit/ASWeakProxy.h>
|
||||
|
||||
#define _node (_shouldInvertStrongReference ? _weakNode : _strongNode)
|
||||
|
||||
@ -74,7 +75,7 @@
|
||||
_weakNode = nil;
|
||||
}
|
||||
|
||||
node.interfaceStateDelegate = self;
|
||||
[node addInterfaceStateDelegate:self];
|
||||
}
|
||||
|
||||
- (void)setNode:(ASDisplayNode *)node
|
||||
|
||||
@ -138,9 +138,6 @@ __unused static NSString * _Nonnull NSStringFromASHierarchyStateChange(ASHierarc
|
||||
// Returns the bounds of the node without reaching the view or layer
|
||||
- (CGRect)_locked_threadSafeBounds;
|
||||
|
||||
// delegate to inform of ASInterfaceState changes (used by ASNodeController)
|
||||
@property (nonatomic, weak) id<ASInterfaceStateDelegate> interfaceStateDelegate;
|
||||
|
||||
// The -pendingInterfaceState holds the value that will be applied to -interfaceState by the
|
||||
// ASCATransactionQueue. If already applied, it matches -interfaceState. Thread-safe access.
|
||||
@property (nonatomic, readonly) ASInterfaceState pendingInterfaceState;
|
||||
|
||||
@ -241,6 +241,8 @@ AS_EXTERN NSString * const ASRenderingEngineDidDisplayNodesScheduledBeforeTimest
|
||||
NSTimeInterval _debugTimeToAddSubnodeViews;
|
||||
NSTimeInterval _debugTimeForDidLoad;
|
||||
#endif
|
||||
|
||||
NSHashTable <id <ASInterfaceStateDelegate>> *_interfaceStateDelegates;
|
||||
}
|
||||
|
||||
+ (void)scheduleNodeForRecursiveDisplay:(ASDisplayNode *)node;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user