Asyncdisplaykit: [ASCellNode] shadowRadius + shadowColor doesn't appear to work for CollectionCell nodes

Created on 23 Dec 2015  Â·  6Comments  Â·  Source: facebookarchive/AsyncDisplayKit

I can't seem to draw shadows for ASCellNodes.

My first stab: I ran CustomCollectionView, and modified [ImageCellNode initWithImage:] thus:

- (id)initWithImage:(UIImage *)image
{
  self = [super init];
  if (self != nil) {
    _imageNode = [[ASImageNode alloc] init];
    _imageNode.image = image;

    [self addSubnode:_imageNode];

    // both `self.layer.` and `self.` fails to draw a shadow.
    self.layer.shadowRadius = 20.f;
    self.layer.shadowColor = [UIColor blackColor].CGColor;
    self.layer.shadowOffset = CGSizeMake(0, 1.f);
  }
  return self;
}

No shadow drawn.

I have UICollectionViewCells that draw their shadows with layer this way. ASDK doesn't seem to match this behaviour, despite Nodes supposedly being drop-in-replacements.

Most helpful comment

@hashemp206 it looks like ASDisplayNode has no shadowPath property.
Did you mean self.layer.shadowPath?

I just tried it, but I cannot access self.layer.shadowPath from init*. This is probably because the layer isn't created at that point... so where's a good place to place that line of code?

EDIT: I found that didLoad: is a great place to put it! e.g.

- (void)didLoad {
    [super didLoad];

    self.layer.shadowPath = [UIBezierPath bezierPathWithRect:self.bounds].CGPath;
}

All 6 comments

by default, shadow is clipped!

add self.clipsToBounds = NO; to fix it

@hashemp206 thanks, but that doesn't seem to have worked. The initWithImage: now looks like:

- (id)initWithImage:(UIImage *)image
{
  self = [super init];
  if (self != nil) {
    _imageNode = [[ASImageNode alloc] init];
    _imageNode.image = image;
    [self addSubnode:_imageNode];

    // both `self.layer.` and `self.` fails to draw a shadow.
    self.layer.shadowRadius = 20.f;
    self.layer.shadowColor = [UIColor blackColor].CGColor;
    self.layer.shadowOffset = CGSizeMake(0, 1.f);
    self.clipsToBounds = NO;
  }
  return self;
}

you also need to set shadowOpacity = 1;

self.shadowColor = [UIColor colorWithWhite:0 alpha:0.5].CGColor;
self.shadowOffset = CGSizeMake(0, 2.5);
self.shadowOpacity = 1;
self.shadowRadius = 5;
self.clipsToBounds = NO;

@hashemp206 Thanks — adding shadowOpacity appeared to have worked. However, I found that enabling shadow dropped frames when scrolling.

add this:

self.shadowPath = [UIBezierPath bezierPathWithRect:self.bounds].CGPath;

as scrolling occurs, layer continuously redraw its shadow .
above code tells the layer the exact path it should use to draw shadow. which increase frame rate a lot.
if you don't use shadowPath the layer tries to do shadow calculation for its inner bounds too which you don't need.

@hashemp206 it looks like ASDisplayNode has no shadowPath property.
Did you mean self.layer.shadowPath?

I just tried it, but I cannot access self.layer.shadowPath from init*. This is probably because the layer isn't created at that point... so where's a good place to place that line of code?

EDIT: I found that didLoad: is a great place to put it! e.g.

- (void)didLoad {
    [super didLoad];

    self.layer.shadowPath = [UIBezierPath bezierPathWithRect:self.bounds].CGPath;
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

Luis-X picture Luis-X  Â·  7Comments

modLX4 picture modLX4  Â·  8Comments

GreatLiyi picture GreatLiyi  Â·  3Comments

Adlai-Holler picture Adlai-Holler  Â·  4Comments

nannanIT picture nannanIT  Â·  10Comments