Andy Bayer
Andy Bayer

Reputation: 77

CAGradientLayer scrolls with UIScrollView

I'm attempting to add a CAGradientLayer overtop of a UIScrollView to fade the edges into transparency.

The gradient is correct, but the mask I'm adding moves when the UIScrollView scrolls.

I've attempted to commit the CATransaction but it is still not successful.

- (void)layoutSubviews
{
    [super layoutSubviews];

    [CATransaction begin];
    [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];

    NSObject * transparent = (NSObject *) [[UIColor colorWithWhite:0 alpha:0] CGColor];
    NSObject * opaque = (NSObject *) [[UIColor colorWithWhite:0 alpha:1] CGColor];

    CAGradientLayer* hMaskLayer = [CAGradientLayer layer];
    hMaskLayer.opacity = .7;
    hMaskLayer.colors = [NSArray arrayWithObjects:transparent, opaque, opaque, transparent, nil];
    hMaskLayer.locations = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0],
                        [NSNumber numberWithFloat:0.2],
                        [NSNumber numberWithFloat:0.8],
                        [NSNumber numberWithFloat:1.0], nil];
    hMaskLayer.startPoint = CGPointMake(0, 0.5);
    hMaskLayer.endPoint = CGPointMake(1.0, 0.5);
    hMaskLayer.bounds = self.bounds;
    hMaskLayer.anchorPoint = CGPointZero;

    self.layer.mask = hMaskLayer;

    [CATransaction commit];
}

Upvotes: 2

Views: 541

Answers (1)

matt
matt

Reputation: 535925

the mask I'm adding moves when the UIScrollView scrolls

Not surprising, because the layer's position is based on the bounds of its superlayer, and the bounds is exactly what changes when scrolling.

Simple solution: put the scroll view in a superview with exactly the same size and mask that superview's layer.

Upvotes: 2

Related Questions