mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-24 07:05:35 +00:00
Initial attempt at implementing Display Traits
Initial attempt to get display traits working with ASEnvironment. To get proper ASDisplayTraits support, you must use an ASViewController. The ASViewController implements UITraitCollection-related methods (`traitCollectionDidChange:`, `willTransitionToTraitCollection:withTransitionCoordinator:`, viewWillTransitionToSize:withTransitionCoordinator`) to update the internal ASDisplayTraits and propagate them to subnodes. ASTableNode and ASCollectionNode don't actually have their cells as subnodes, so a little bit of trickery is involved (on `setEnvironment:` the table/collection node gets its data controllers completedNodes and propagates the new traits. see `ASDisplayTraitsCollectionTableSetEnvironmentState`). The data controller also passes the current display traits when creating new cells. ASViewController also supports the ability to return a custom set of display traits. So if you have a modal dialog that should always be told it is in a compact size class, you can set the override block before displaying the VC. A new example, called Display Traits, has been added. It shows how display traits can be used in a ASViewController with a normal ASDisplayNode as its root, as well as in ASViewControllers hosting table nodes and collection nodes. There is also an example of overriding the default display traits of a VC. Please provide feedback!
This commit is contained in:
164
AsyncDisplayKit/ASTableNode.mm
Normal file
164
AsyncDisplayKit/ASTableNode.mm
Normal file
@@ -0,0 +1,164 @@
|
||||
//
|
||||
// ASTableNode.m
|
||||
// AsyncDisplayKit
|
||||
//
|
||||
// Created by Steven Ramkumar on 11/4/15.
|
||||
// Copyright © 2015 Facebook. All rights reserved.
|
||||
//
|
||||
|
||||
#import "ASEnvironmentInternal.h"
|
||||
#import "ASFlowLayoutController.h"
|
||||
#import "ASTableViewInternal.h"
|
||||
#import "ASDisplayNode+Subclasses.h"
|
||||
#import "ASRangeControllerUpdateRangeProtocol+Beta.h"
|
||||
|
||||
@interface _ASTablePendingState : NSObject
|
||||
@property (weak, nonatomic) id <ASTableDelegate> delegate;
|
||||
@property (weak, nonatomic) id <ASTableDataSource> dataSource;
|
||||
@end
|
||||
|
||||
@implementation _ASTablePendingState
|
||||
@end
|
||||
|
||||
@interface ASTableNode ()
|
||||
@property (nonatomic, strong) _ASTablePendingState *pendingState;
|
||||
@end
|
||||
|
||||
@interface ASTableView ()
|
||||
- (instancetype)_initWithFrame:(CGRect)frame style:(UITableViewStyle)style dataControllerClass:(Class)dataControllerClass;
|
||||
@end
|
||||
|
||||
@implementation ASTableNode
|
||||
|
||||
- (instancetype)_initWithTableView:(ASTableView *)tableView
|
||||
{
|
||||
// Avoid a retain cycle. In this case, the ASTableView is creating us, and strongly retains us.
|
||||
ASTableView * __weak weakTableView = tableView;
|
||||
if (self = [super initWithViewBlock:^UIView *{ return weakTableView; }]) {
|
||||
__unused __weak ASTableView *view = [self view];
|
||||
return self;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (instancetype)_initWithFrame:(CGRect)frame style:(UITableViewStyle)style dataControllerClass:(Class)dataControllerClass
|
||||
{
|
||||
ASDisplayNodeViewBlock tableViewBlock = ^UIView *{
|
||||
return [[ASTableView alloc] _initWithFrame:frame style:style dataControllerClass:dataControllerClass ownedByNode:YES];
|
||||
};
|
||||
|
||||
if (self = [super initWithViewBlock:tableViewBlock]) {
|
||||
return self;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (instancetype)initWithStyle:(UITableViewStyle)style
|
||||
{
|
||||
return [self _initWithFrame:CGRectZero style:style dataControllerClass:nil];
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
return [self _initWithFrame:CGRectZero style:UITableViewStylePlain dataControllerClass:nil];
|
||||
}
|
||||
|
||||
- (void)didLoad
|
||||
{
|
||||
[super didLoad];
|
||||
|
||||
ASTableView *view = self.view;
|
||||
view.tableNode = self;
|
||||
|
||||
if (_pendingState) {
|
||||
_ASTablePendingState *pendingState = _pendingState;
|
||||
self.pendingState = nil;
|
||||
view.asyncDelegate = pendingState.delegate;
|
||||
view.asyncDataSource = pendingState.dataSource;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)updateCurrentRangeWithMode:(ASLayoutRangeMode)rangeMode
|
||||
{
|
||||
if (!self.isNodeLoaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
[self.view.rangeController updateCurrentRangeWithMode:rangeMode];
|
||||
}
|
||||
|
||||
- (_ASTablePendingState *)pendingState
|
||||
{
|
||||
if (!_pendingState && ![self isNodeLoaded]) {
|
||||
self.pendingState = [[_ASTablePendingState alloc] init];
|
||||
}
|
||||
ASDisplayNodeAssert(![self isNodeLoaded] || !_pendingState, @"ASTableNode should not have a pendingState once it is loaded");
|
||||
return _pendingState;
|
||||
}
|
||||
|
||||
- (void)setDelegate:(id <ASTableDelegate>)delegate
|
||||
{
|
||||
if ([self pendingState]) {
|
||||
_pendingState.delegate = delegate;
|
||||
} else {
|
||||
ASDisplayNodeAssert([self isNodeLoaded], @"ASTableNode should be loaded if pendingState doesn't exist");
|
||||
self.view.asyncDelegate = delegate;
|
||||
}
|
||||
}
|
||||
|
||||
- (id <ASTableDelegate>)delegate
|
||||
{
|
||||
if ([self pendingState]) {
|
||||
return _pendingState.delegate;
|
||||
} else {
|
||||
return self.view.asyncDelegate;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setDataSource:(id <ASTableDataSource>)dataSource
|
||||
{
|
||||
if ([self pendingState]) {
|
||||
_pendingState.dataSource = dataSource;
|
||||
} else {
|
||||
ASDisplayNodeAssert([self isNodeLoaded], @"ASTableNode should be loaded if pendingState doesn't exist");
|
||||
self.view.asyncDataSource = dataSource;
|
||||
}
|
||||
}
|
||||
|
||||
- (id <ASTableDataSource>)dataSource
|
||||
{
|
||||
if ([self pendingState]) {
|
||||
return _pendingState.dataSource;
|
||||
} else {
|
||||
return self.view.asyncDataSource;
|
||||
}
|
||||
}
|
||||
|
||||
- (ASTableView *)view
|
||||
{
|
||||
return (ASTableView *)[super view];
|
||||
}
|
||||
|
||||
#if ASRangeControllerLoggingEnabled
|
||||
- (void)visibilityDidChange:(BOOL)isVisible
|
||||
{
|
||||
[super visibilityDidChange:isVisible];
|
||||
NSLog(@"%@ - visible: %d", self, isVisible);
|
||||
}
|
||||
#endif
|
||||
|
||||
- (void)clearContents
|
||||
{
|
||||
[super clearContents];
|
||||
[self.view clearContents];
|
||||
}
|
||||
|
||||
- (void)clearFetchedData
|
||||
{
|
||||
[super clearFetchedData];
|
||||
[self.view clearFetchedData];
|
||||
}
|
||||
|
||||
ASDisplayTraitsCollectionTableSetEnvironmentState
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user