Thyraz
Thyraz

Reputation: 2432

Using UIGradientLayer as layer.mask to fade out bottom / top of a scrollview --> repositioning of mask is lagging behind

I have a subclass of UIScrollView which should be faded out at top / bottom. (From opaque to clearColor, like the Notes.app does at the bottom of the DetailView.)

So I added a UIGradientLayer as scrollview.layer.mask which seemed to work fine until I scrolled the first time:

    CAGradientLayer *mask = [CAGradientLayer layer];
    mask.locations = [NSArray arrayWithObjects:
                      [NSNumber numberWithFloat:0.0],
                      [NSNumber numberWithFloat:0.1],
                      [NSNumber numberWithFloat:0.9],
                      [NSNumber numberWithFloat:1.0],
                      nil];

    mask.colors = [NSArray arrayWithObjects:
                   (__bridge id)[UIColor clearColor].CGColor,
                   (__bridge id)[UIColor whiteColor].CGColor,
                   (__bridge id)[UIColor whiteColor].CGColor,
                   (__bridge id)[UIColor clearColor].CGColor,
                   nil];

    mask.frame = self.scrollview.bounds;
    // vertical direction
    mask.startPoint = CGPointMake(0, 0); 
    mask.endPoint = CGPointMake(0, 1);

    self.scrollview.layer.mask = mask;

But when I scrolled, the mask scrolled with the content instead of sticking on the screen position to fade out the content nicely.

I kind of fixed that by reposition the mask in the scrollviews layoutSubviews:

-(void)layoutSubviews {
    [super layoutSubviews];

    CGRect layerMaskFrame = self.layer.mask.frame;
    layerMaskFrame.origin = [self convertPoint:self.bounds.origin toView:self];

    self.layer.mask.frame = layerMaskFrame;
}

But now the movement of the mask is kind of delayed when I scroll. It looks like the frame of the mask is set with a delay and animated.

Both, the scrolling and the movement of the mask ist smooth, so I don't think it's a problem with too slow hardware.

But how can that be? layoutSubviews shouldn't be called from a animation, and I set the new frame immediately there...

Upvotes: 2

Views: 2503

Answers (1)

Giulio Petek
Giulio Petek

Reputation: 76

Referring to this article http://cocoawithlove.com/2009/08/adding-shadow-effects-to-uitableview.html you have to surround your frame changes like this:

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

// Set the frame

[CATransaction commit];

With this it should happen without any animations. Hope this works :)

Upvotes: 6

Related Questions