adding fading color & transparency to UIView
Asked Answered
G

7

7

I know how to create and animate a view like the one in the Share sub view of the new app store app that comes with iOS 6+ (see attached screenshot), but I don't know how to add that nice coloring effect with transparency on this view. anyone can provide a code sample to make a UIView looks exactly the one in the screenshot?

P.S. the alpha property alone of UIView does not do such thing.

enter image description here

Gilmer answered 13/2, 2013 at 13:29 Comment(0)
B
31

You can add this method to a UIView category and reuse as needed. It applies a linear black gradient from "theColor" to transparent to the given view.

You should have QuartzCore.framework in your project in order to use the CAGradientLayer object.

+ (void)addLinearGradientToView:(UIView *)theView withColor:(UIColor *)theColor transparentToOpaque:(BOOL)transparentToOpaque
{
    CAGradientLayer *gradient = [CAGradientLayer layer];

    //the gradient layer must be positioned at the origin of the view
    CGRect gradientFrame = theView.frame;
    gradientFrame.origin.x = 0;
    gradientFrame.origin.y = 0;
    gradient.frame = gradientFrame;

    //build the colors array for the gradient
    NSArray *colors = [NSArray arrayWithObjects:
                       (id)[theColor CGColor],
                       (id)[[theColor colorWithAlphaComponent:0.9f] CGColor],
                       (id)[[theColor colorWithAlphaComponent:0.6f] CGColor],
                       (id)[[theColor colorWithAlphaComponent:0.4f] CGColor],
                       (id)[[theColor colorWithAlphaComponent:0.3f] CGColor],
                       (id)[[theColor colorWithAlphaComponent:0.1f] CGColor],
                       (id)[[UIColor clearColor] CGColor],
                       nil];

    //reverse the color array if needed
    if(transparentToOpaque)
    {
       colors = [[colors reverseObjectEnumerator] allObjects];
    }

    //apply the colors and the gradient to the view
    gradient.colors = colors;

    [theView.layer insertSublayer:gradient atIndex:0];
}

Please note that you should have the backgroundColor of theView set to clearColor so that it doesn't interfere with the gradient. Also, for the results shown in the screenshot, the transparentToOpaque flag should be YES.

Bienne answered 18/2, 2013 at 16:51 Comment(3)
I have done what you said exactly but the code has no effect, I called the method like this in viewDidLoad: [UIView addLinearGradientToView:self.testView withColor:[UIColor redColor] transparentToOpaque:YES]; of course I created the category without problems. I'm testing on iOS 6 simulator and QuartzCore framework is also added and imported to this View's page.Gilmer
I forgot to set the layer's origin to (0,0). I've edited the post to reflect the change. You can play around with the alpha components in the colors array to give a "non linear" gradient if you want.Bienne
Nice tip: Please note that you should have the backgroundColor of theView set to clearColor!Diaphysis
F
6

Here is PedroSilva's solution translated to Swift if anyone needs it (added vertical option as well)

class func addLinearGradientToView(view: UIView, colour: UIColor, transparntToOpaque: Bool, vertical: Bool)
{
    let gradient = CAGradientLayer()
    let gradientFrame = CGRectMake(0, 0, view.frame.size.width, view.frame.size.height)
    gradient.frame = gradientFrame

    var colours = [
        colour.CGColor,
        colour.colorWithAlphaComponent(0.9).CGColor,
        colour.colorWithAlphaComponent(0.8).CGColor,
        colour.colorWithAlphaComponent(0.7).CGColor,
        colour.colorWithAlphaComponent(0.6).CGColor,
        colour.colorWithAlphaComponent(0.5).CGColor,
        colour.colorWithAlphaComponent(0.4).CGColor,
        colour.colorWithAlphaComponent(0.3).CGColor,
        colour.colorWithAlphaComponent(0.2).CGColor,
        colour.colorWithAlphaComponent(0.1).CGColor,
        UIColor.clearColor().CGColor
    ]

    if transparntToOpaque == true
    {
        colours = colours.reverse()
    }

    if vertical == true
    {
        gradient.startPoint = CGPointMake(0, 0.5)
        gradient.endPoint = CGPointMake(1, 0.5)
    }
    gradient.colors = colours
    view.layer.insertSublayer(gradient, atIndex: 0)
}
Felske answered 11/9, 2015 at 12:48 Comment(0)
G
4
CAGradientLayer *layer = [CAGradientLayer layer];
layer.frame = yourView.bounds;
UIColor *blackColor = [UIColor colorWithWhite:0.42f alpha:1.0f];
UIColor *clearColor = [UIColor colorWithWhite:0.42f alpha:0.0f];
layer.colors = [NSArray arrayWithObjects:(id)clearColor.CGColor, (id)blackColor.CGColor, nil];
[myView.layer insertSublayer:layer atIndex:0];

Where layer is the layer of your view.

Gorges answered 13/2, 2013 at 13:37 Comment(6)
this sample produces this crash: [CALayer setColors:]: unrecognized selector sent to instanceGilmer
What is the Class of your view object?Gorges
my view is simply a subclass of UIViewGilmer
your updated code give me this color on the subview: dl.dropbox.com/u/57066689/mySubView.jpg the sub view has the button with text "test". i put some alpha but it is still far from the above glossy viewGilmer
and as @Bird suggested use myView.opaque = NO;Ballade
Try to play with colors. For example, use: UIColor *blackColor = [UIColor colorWithWhite:0.3f alpha:0.7f]; UIColor *clearColor = [UIColor colorWithWhite:0.0f alpha:0.7f];Gorges
G
3

You can simply use a semi transparent png as a background to get the effect like this. Make sure you set the UIView's opaque to NO and you will be fine.

Growing answered 16/2, 2013 at 2:17 Comment(1)
Good answer and easy. Also, the PNG can be small such as 10x10(or even 1x1) and then tiled so it doesn't weigh alot.Augsburg
E
3

There is no magic needed for this effect to be achieved. You should do it like Apple does it. UIImageViews with small, stretched images.

This view (the bottom-half square that includes the icons) uses an image that stretches and produces this effect.

You should follow this method too. Your views will be very light and it will just cost you a few tests in Photoshop to achieve the correct effect.

As I have noticed, Apple never uses gradient layers on the iPhone. It must be significantly more GPU consuming because it would have saved them a lot of images...

Here's a similar image to test with. enter image description here

Hope it helps.

Ectoparasite answered 20/2, 2013 at 4:14 Comment(0)
V
2

You just need to set the view's background color's alpha value to your desired value.

See attached zip code. Go to AlphaViewController's nib file and see it there

I have only set the alpha value for the subview to 70%. You can do it according to your requirements.

Vanward answered 20/2, 2013 at 4:55 Comment(0)
C
1

In Case if anyone need Swift 3.X

func addLinearGradientToView(view: UIView, colour: UIColor, transparntToOpaque: Bool, vertical: Bool)
    {
        let gradient = CAGradientLayer()
        let gradientFrame = CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height)
        gradient.frame = gradientFrame

        var colours = [
            colour.cgColor,
            colour.withAlphaComponent(0.9).cgColor,
            colour.withAlphaComponent(0.8).cgColor,
            colour.withAlphaComponent(0.7).cgColor,
            colour.withAlphaComponent(0.6).cgColor,
            colour.withAlphaComponent(0.5).cgColor,
            colour.withAlphaComponent(0.4).cgColor,
            colour.withAlphaComponent(0.3).cgColor,
            colour.withAlphaComponent(0.2).cgColor,
            colour.withAlphaComponent(0.1).cgColor,
            UIColor.clear.cgColor
        ]

        if transparntToOpaque == true
        {
            colours = colours.reversed()
        }

        if vertical == true
        {
            gradient.startPoint =  CGPoint(x: 0, y: 0.5)
            gradient.endPoint = CGPoint(x: 0, y: 0.5)
        }
        gradient.colors = colours
        view.layer.insertSublayer(gradient, at: 0)
    }

Other way in Swift 3.x

let gradient = CAGradientLayer()
gradient.frame = view.bounds
gradient.colors = [UIColor.blue.cgColor, UIColor.white.cgColor]
view.layer.insertSublayer(gradient, at: 0)
Civilian answered 30/5, 2017 at 9:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.