Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a top fade effect using UIScrollView?

I've got a UIScrollView in my app and I have seen in some other apps that when the user scrolls, the top section fades out on scroll rather than just dissapearing out.

I really love this effect and want to achieve it. Any ideas how it can be done?

like image 384
Omar Avatar asked Jul 21 '13 17:07

Omar


3 Answers

Simple 2020 solution:

import UIKit

class FadeTail: UIIView {
    
    private lazy var gradientLayer: CAGradientLayer = {
        let l = CAGradientLayer()
        l.startPoint = CGPoint(x: 0.5, y: 0)
        l.endPoint = CGPoint(x: 0.5, y: 1)
        let baseColor = UIColor.white // for example
        l.colors = [
            baseColor.withAlphaComponent(0),
            baseColor.withAlphaComponent(1),
        ].map{$0.cgColor}
        layer.addSublayer(l)
        return l
    }()
    
    override func layoutSubviews() {
        super.layoutSubviews()
        gradientLayer.frame = bounds
    }
}

Simply

  • autolayout that view in storyboard,
  • any shape or size you wish
  • on top of the view (text, image, webview, anything) you wish to be faded.

Easy.

enter image description here

Tip - gradients, circles, etc

If you need crazy circular/banded/etc fades, use the techniques here: https://stackoverflow.com/a/61174086/294884

enter image description here

like image 156
Fattie Avatar answered Nov 15 '22 01:11

Fattie


EDIT: I've put this code up on github, see here.


See my answer to a similar question.

My solution is to subclass UIScrollView, and create a mask layer in the layoutSubviews method.

#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

The code above fades the top and bottom of the UIScrollView from the background colour to transparent, but this can be easily changed to fade the top only (or fade to any colour you want).

Change this line to fade the top only:

// Fade top of scrollview only
gradientLayer.locations = [NSArray arrayWithObjects:
                           [NSNumber numberWithFloat:0],
                           [NSNumber numberWithFloat:fadePercentage],
                           [NSNumber numberWithFloat:1],
                           [NSNumber numberWithFloat:1], nil];

EDIT 2:

Or fade the top only by changing these two lines:

// Fade top of scrollview only
    gradientLayer.colors = [NSArray arrayWithObjects: transparent, opaque, nil];

    gradientLayer.locations = [NSArray arrayWithObjects: [NSNumber numberWithFloat:0],
                                                         [NSNumber numberWithFloat:fadePercentage], nil];

Or, fade the bottom only:

// Fade bottom of scrollview only
    gradientLayer.colors = [NSArray arrayWithObjects: opaque, transparent, nil];

    gradientLayer.locations = [NSArray arrayWithObjects: [NSNumber numberWithFloat:1.0 - fadePercentage],
                                                         [NSNumber numberWithFloat:1], nil];
like image 44
Steph Sharp Avatar answered Nov 15 '22 00:11

Steph Sharp


You can use a CAGradientLayer by

  1. Adding the QuartzCore.framework to your project (see Linking to Library or Framework).

  2. Add #import of the QuartzCore headers:

    #import <QuartzCore/QuartzCore.h>
    
  3. And then use CAGradientLayer:

    - (void)addGradientMaskToView:(UIView *)view
    {
        CAGradientLayer *gradient = [CAGradientLayer layer];
        gradient.frame = view.bounds;
        gradient.colors = @[(id)[[UIColor clearColor] CGColor], (id)[[UIColor whiteColor] CGColor]];
        gradient.startPoint = CGPointMake(0.5, 0.0); // this is the default value, so this line is not needed
        gradient.endPoint = CGPointMake(0.5, 0.20);
    
        [view.layer setMask:gradient];
    }
    

Note, this CAGradientLayer is a gradient from a color with alpha of 0.0 (e.g. clearColor) to a color to a color with alpha of 1.0 (e.g. whiteColor), not just from black to white. You can adjust the startPoint (the default value is probably fine) and the endPoint to adjust where you want the gradient to be applied.

And generally, when doing this with a UIScrollView, unless you want the gradient to scroll with you, you make the UIScrollView a subview of some other UIView and apply this gradient to that container view, not the scroll view itself.

like image 9
Rob Avatar answered Nov 15 '22 01:11

Rob