mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-17 11:50:56 +00:00
[ASDisplayNode] Add automatic measurement before layout (#1725)
* 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
This commit is contained in:
parent
a8c5ac138d
commit
359785ac92
@ -17,6 +17,8 @@
|
|||||||
#import <AsyncDisplayKit/ASAsciiArtBoxCreator.h>
|
#import <AsyncDisplayKit/ASAsciiArtBoxCreator.h>
|
||||||
#import <AsyncDisplayKit/ASLayoutable.h>
|
#import <AsyncDisplayKit/ASLayoutable.h>
|
||||||
|
|
||||||
|
#define ASDisplayNodeLoggingEnabled 0
|
||||||
|
|
||||||
@class ASDisplayNode;
|
@class ASDisplayNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -53,8 +53,11 @@ NSString * const ASRenderingEngineDidDisplayNodesScheduledBeforeTimestamp = @"AS
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
//#define LOG(...) NSLog(__VA_ARGS__)
|
#if ASDisplayNodeLoggingEnabled
|
||||||
|
#define LOG(...) NSLog(__VA_ARGS__)
|
||||||
|
#else
|
||||||
#define LOG(...)
|
#define LOG(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
// Conditionally time these scopes to our debug ivars (only exist in debug/profile builds)
|
// Conditionally time these scopes to our debug ivars (only exist in debug/profile builds)
|
||||||
#if TIME_DISPLAYNODE_OPS
|
#if TIME_DISPLAYNODE_OPS
|
||||||
@ -880,7 +883,7 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
|
|||||||
|
|
||||||
- (void)animateLayoutTransition:(id<ASContextTransitioning>)context
|
- (void)animateLayoutTransition:(id<ASContextTransitioning>)context
|
||||||
{
|
{
|
||||||
[self __layoutSublayouts];
|
[self __layoutSubnodes];
|
||||||
[context completeTransition:YES];
|
[context completeTransition:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1114,6 +1117,9 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
|
|||||||
ASDisplayNodeAssertMainThread();
|
ASDisplayNodeAssertMainThread();
|
||||||
ASDN::MutexLocker l(_propertyLock);
|
ASDN::MutexLocker l(_propertyLock);
|
||||||
CGRect bounds = self.bounds;
|
CGRect bounds = self.bounds;
|
||||||
|
|
||||||
|
[self measureNodeWithBoundsIfNecessary:bounds];
|
||||||
|
|
||||||
if (CGRectEqualToRect(bounds, CGRectZero)) {
|
if (CGRectEqualToRect(bounds, CGRectZero)) {
|
||||||
// Performing layout on a zero-bounds view often results in frame calculations
|
// Performing layout on a zero-bounds view often results in frame calculations
|
||||||
// with negative sizes after applying margins, which will cause
|
// with negative sizes after applying margins, which will cause
|
||||||
@ -1132,8 +1138,40 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
|
|||||||
[self layoutDidFinish];
|
[self layoutDidFinish];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)measureNodeWithBoundsIfNecessary:(CGRect)bounds
|
||||||
|
{
|
||||||
|
// Normally measure will be called before layout occurs. If this doesn't happen, nothing is going to call it at all.
|
||||||
|
// We simply call measureWithSizeRange: using a size range equal to whatever bounds were provided to that element
|
||||||
|
if (self.supernode == nil && !self.supportsRangeManagedInterfaceState && [self _hasDirtyLayout]) {
|
||||||
|
if (CGRectEqualToRect(bounds, CGRectZero)) {
|
||||||
|
LOG(@"Warning: No size given for node before node was trying to layout itself: %@. Please provide a frame for the node.", self);
|
||||||
|
} else {
|
||||||
|
[self measureWithSizeRange:ASSizeRangeMake(bounds.size, bounds.size)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)layout
|
||||||
|
{
|
||||||
|
ASDisplayNodeAssertMainThread();
|
||||||
|
|
||||||
|
if ([self _hasDirtyLayout]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
[self __layoutSubnodes];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)__layoutSubnodes
|
||||||
|
{
|
||||||
|
for (ASLayout *subnodeLayout in _layout.sublayouts) {
|
||||||
|
((ASDisplayNode *)subnodeLayout.layoutableObject).frame = [subnodeLayout frame];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (void)layoutDidFinish
|
- (void)layoutDidFinish
|
||||||
{
|
{
|
||||||
|
// Hook for subclasses
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CATransform3D)_transformToAncestor:(ASDisplayNode *)ancestor
|
- (CATransform3D)_transformToAncestor:(ASDisplayNode *)ancestor
|
||||||
@ -2463,24 +2501,6 @@ void recursivelyTriggerDisplayForLayer(CALayer *layer, BOOL shouldBlock)
|
|||||||
[layoutTransition startTransition];
|
[layoutTransition startTransition];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)layout
|
|
||||||
{
|
|
||||||
ASDisplayNodeAssertMainThread();
|
|
||||||
|
|
||||||
if ([self _hasDirtyLayout]) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
[self __layoutSublayouts];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)__layoutSublayouts
|
|
||||||
{
|
|
||||||
for (ASLayout *subnodeLayout in _layout.sublayouts) {
|
|
||||||
((ASDisplayNode *)subnodeLayout.layoutableObject).frame = [subnodeLayout frame];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)displayWillStart
|
- (void)displayWillStart
|
||||||
{
|
{
|
||||||
ASDisplayNodeAssertMainThread();
|
ASDisplayNodeAssertMainThread();
|
||||||
|
|||||||
@ -14,8 +14,7 @@
|
|||||||
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
//
|
//
|
||||||
#import <AsyncDisplayKit/AsyncDisplayKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
#import <AsyncDisplayKit/ASVideoNode.h>
|
|
||||||
|
|
||||||
@interface ViewController : UIViewController
|
@interface ViewController : UIViewController
|
||||||
|
|
||||||
|
|||||||
@ -16,8 +16,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import "ViewController.h"
|
#import "ViewController.h"
|
||||||
#import "ASLayoutSpec.h"
|
#import <AsyncDisplayKit/AsyncDisplayKit.h>
|
||||||
#import "ASStaticLayoutSpec.h"
|
|
||||||
|
|
||||||
@interface ViewController()<ASVideoNodeDelegate>
|
@interface ViewController()<ASVideoNodeDelegate>
|
||||||
@property (nonatomic, strong) ASDisplayNode *rootNode;
|
@property (nonatomic, strong) ASDisplayNode *rootNode;
|
||||||
@ -28,12 +27,13 @@
|
|||||||
|
|
||||||
#pragma mark - UIViewController
|
#pragma mark - UIViewController
|
||||||
|
|
||||||
- (void)viewWillAppear:(BOOL)animated
|
- (void)viewDidLoad
|
||||||
{
|
{
|
||||||
[super viewWillAppear:animated];
|
[super viewDidLoad];
|
||||||
|
|
||||||
// Root node for the view controller
|
// Root node for the view controller
|
||||||
_rootNode = [ASDisplayNode new];
|
_rootNode = [ASDisplayNode new];
|
||||||
|
_rootNode.frame = self.view.bounds;
|
||||||
_rootNode.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
_rootNode.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||||
|
|
||||||
ASVideoNode *guitarVideoNode = self.guitarVideoNode;
|
ASVideoNode *guitarVideoNode = self.guitarVideoNode;
|
||||||
@ -68,16 +68,6 @@
|
|||||||
[self.view addSubnode:_rootNode];
|
[self.view addSubnode:_rootNode];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)viewDidLayoutSubviews
|
|
||||||
{
|
|
||||||
[super viewDidLayoutSubviews];
|
|
||||||
|
|
||||||
// After all subviews are layed out we have to measure it and move the root node to the right place
|
|
||||||
CGSize viewSize = self.view.bounds.size;
|
|
||||||
[self.rootNode measureWithSizeRange:ASSizeRangeMake(viewSize, viewSize)];
|
|
||||||
[self.rootNode setNeedsLayout];
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - Getter / Setter
|
#pragma mark - Getter / Setter
|
||||||
|
|
||||||
- (ASVideoNode *)guitarVideoNode;
|
- (ASVideoNode *)guitarVideoNode;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user