ASCellNode
ASCellNode
, as you may have guessed, is the cell class of Texture. Unlike the various cells in UIKit, ASCellNode
can be used with ASTableNodes
, ASCollectionNodes
and ASPagerNodes
, making it incredibly flexible.
3 Ways to Party
There are three ways in which you can implement the cells you’ll use in your Texture app: subclassing ASCellNode
, initializing with an existing ASDKViewController
or using an existing UIView or CALayer
.
Subclassing
Subclassing an ASCellNode
is pretty much the same as subclassing a regular ASDisplayNode
.
Most likely, you’ll write a few of the following:
-init
– Thread safe initialization.-layoutSpecThatFits:
– Return a layout spec that defines the layout of your cell.-didLoad
– Called on the main thread. Good place to add gesture recognizers, etc.-layout
– Also called on the main thread. Layout is complete after the call to super which means you can do any extra tweaking you need to do.
Initializing with an ASDKViewController
Say you already have some type of view controller written to display a view in your app. If you want to take that view controller and drop its view in as a cell in one of the scrolling nodes or a pager node its no problem.
For example, say you already have a view controller written that manages an ASTableNode
. To use that table as a page in an ASPagerNode
you can use -initWithViewControllerBlock
.
- (ASCellNode *)pagerNode:(ASPagerNode *)pagerNode nodeAtIndex:(NSInteger)index
{
NSArray *animals = self.allAnimals[index];
ASCellNode *node = [[ASCellNode alloc] initWithViewControllerBlock:^UIViewController * _Nonnull{
return [[AnimalTableNodeController alloc] initWithAnimals:animals];
} didLoadBlock:nil];
node.style.preferredSize = pagerNode.bounds.size;
return node;
}
And this works for any combo of scrolling container node and UIViewController
subclass. You want to embed random view controllers in your collection node? Go for it.
.style.preferredSize
of a node created this way. Normally your nodes will implement -layoutSpecThatFits:
but since these don't you'll need give the cell a size.
Initializing with a UIView
or CALayer
Alternatively, if you already have a UIView
or CALayer
subclass that you’d like to drop in as cell you can do that instead.
- (ASCellNode *)pagerNode:(ASPagerNode *)pagerNode nodeAtIndex:(NSInteger)index
{
NSArray *animal = self.animals[index];
ASCellNode *node = [[ASCellNode alloc] initWithViewBlock:^UIView * _Nonnull{
return [[SomeAnimalView alloc] initWithAnimal:animal];
}];
node.style.preferredSize = pagerNode.bounds.size;
return node;
}
As you can see, its roughly the same idea. That being said, if you’re doing this, you may consider converting the existing UIView
subclass to be an ASCellNode
subclass in order to gain the advantage of asynchronous display.
Never Show Placeholders
Usually, if a cell hasn’t finished its display pass before it has reached the screen it will show placeholders until it has completed drawing its content.
If placeholders are unacceptable, you can set an ASCellNode
’s neverShowPlaceholders
property to YES
.
node.neverShowPlaceholders = YES;
With this property set to YES
, the main thread will be blocked until display has completed for the cell. This is more similar to UIKit, and in fact makes Texture scrolling visually indistinguishable from UIKit’s, except being faster.
rangeTuningParameters
are set to 0 this option outperforms UIKit. While the main thread is waiting, subnode display executes concurrently.
UITableViewCell
specific propertys
UITableViewCell
has properties like selectionStyle
, accessoryType
and seperatorInset
that many of us use sometimes to give the Cell more detail. For this case ASCellNode
has the same (passthrough) properties that can be used.
UITableViewCell
contains ASCellNode
as a subview. Depending how your ASLayoutSpec
is defined it may occur that your Layout overlays the UITableViewCell.accessoryView
and therefore is not visible. Make sure that your Layout doesn't overlay any of UITableViewCell
's specific properties.