I have a UIScrollView, and I need the bottom to fade to transparent, so that it does not abruptly cut off the content. The background of the UIScrollView is a custom color.
The approach I used was to subclass UIScrollView
, and create the mask layer in the layoutSubviews
method.
Here's my code, which fades the top and bottom of the UIScrollView
from the background colour to transparent:
#import "FadingScrollView.h"
#import <QuartzCore/QuartzCore.h>
static float const fadePercentage = 0.2;
@implementation FadingScrollView
// ...
- (void)layoutSubviews
{
[super layoutSubviews];
NSObject * transparent = (NSObject *) [[UIColor colorWithWhite:0 alpha:0] CGColor];
NSObject * opaque = (NSObject *) [[UIColor colorWithWhite:0 alpha:1] CGColor];
CALayer * maskLayer = [CALayer layer];
maskLayer.frame = self.bounds;
CAGradientLayer * gradientLayer = [CAGradientLayer layer];
gradientLayer.frame = CGRectMake(self.bounds.origin.x, 0,
self.bounds.size.width, self.bounds.size.height);
gradientLayer.colors = [NSArray arrayWithObjects: transparent, opaque,
opaque, transparent, nil];
// Set percentage of scrollview that fades at top & bottom
gradientLayer.locations = [NSArray arrayWithObjects:
[NSNumber numberWithFloat:0],
[NSNumber numberWithFloat:fadePercentage],
[NSNumber numberWithFloat:1.0 - fadePercentage],
[NSNumber numberWithFloat:1], nil];
[maskLayer addSublayer:gradientLayer];
self.layer.mask = maskLayer;
}
@end
If you just want to fade the bottom, change this line:
// Fade bottom of scrollview only
gradientLayer.locations = [NSArray arrayWithObjects:
[NSNumber numberWithFloat:0],
[NSNumber numberWithFloat:0],
[NSNumber numberWithFloat:1.0 - fadePercentage],
[NSNumber numberWithFloat:1], nil];
When I was implementing this myself, I found this SO question helpful, and this gist on github.
EDIT: I've put this code up on github, see here.
Really like Steph Sharp's implementation, I converted it to swift and thought I'd share in case anyone else needs it.
let fadePercentage = CGFloat(0.2)
override func layoutSubviews() {
super.layoutSubviews()
var transparent = UIColor.clearColor().CGColor
var opaque = UIColor.blackColor().CGColor
var maskLayer = CALayer()
maskLayer.frame = self.bounds
var gradientLayer = CAGradientLayer()
gradientLayer.frame = CGRectMake(self.bounds.origin.x, 0, self.bounds.size.width, self.bounds.size.height)
gradientLayer.colors = [transparent, opaque, opaque, transparent]
gradientLayer.locations = [0, fadePercentage, 1 - fadePercentage, 1]
maskLayer.addSublayer(gradientLayer)
self.layer.mask = maskLayer
}
Theres also this answer which does not include any subclassing.
Here goes the swift 3 version of Steph's answer:
let fadePercentage: Double = 0.2
override func layoutSubviews() {
super.layoutSubviews()
let transparent = UIColor.clear.cgColor
let opaque = UIColor.black.cgColor
let maskLayer = CALayer()
maskLayer.frame = self.bounds
let gradientLayer = CAGradientLayer()
gradientLayer.frame = CGRect(x: self.bounds.origin.x, y: 0, width: self.bounds.size.width, height: self.bounds.size.height)
gradientLayer.colors = [transparent, opaque, opaque, transparent]
gradientLayer.locations = [0, NSNumber(floatLiteral: fadePercentage), NSNumber(floatLiteral: 1 - fadePercentage), 1]
maskLayer.addSublayer(gradientLayer)
self.layer.mask = maskLayer
}