Egil
Egil

Reputation: 195

Gradient mask on UIView

I have a UIView and want to have the bottom part of it fade out to 0 opacity.

May this be done to a UIView (CALayer) in order to affect an entire UIView and its content?

Upvotes: 15

Views: 11930

Answers (2)

Mojtaba Hosseini
Mojtaba Hosseini

Reputation: 119310

Using an Image as the mask to prevent Layout issues.

Although Vladimir's answer is correct, the issue is to sync the gradient layer after view changes. For example when you rotate the phone or resizing the view. So instead of a layer, you can use an image for that:

@IBDesignable
class MaskableLabel: UILabel {
    var maskImageView = UIImageView()

    @IBInspectable
    var maskImage: UIImage? {
        didSet {
            maskImageView.image = maskImage
            updateView()
        }
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        updateView()
    }

    func updateView() {
        if maskImageView.image != nil {
            maskImageView.frame = bounds
            mask = maskImageView
        }
    }
}

Then with a simple gradient mask like this, You can see it even right in the storyboard.

Preview

Note:

You can use this class and replace UILabel with any other view you like to subclass.

🎁 Bones:

You can use any other shaped image as the mask just like that.

Upvotes: 2

Vladimir
Vladimir

Reputation: 170839

Yes, you can do that by setting CAGradientLayer as your view's layer mask:

#import <QuartzCore/QuartzCore.h>

...

CAGradientLayer *maskLayer = [CAGradientLayer layer];

maskLayer.frame = view.bounds;
maskLayer.colors = @[(id)[UIColor whiteColor].CGColor, (id)[UIColor clearColor].CGColor];
maskLayer.startPoint = CGPointMake(0.5, 0);
maskLayer.endPoint = CGPointMake(0.5, 1.0);

view.layer.mask = maskLayer;

P.S. You also need to link QuartzCore.framework to your app to make things work.

Upvotes: 35

Related Questions