pavel_s
pavel_s

Reputation: 505

Create gradient-based UICollectionViewCell background colour

I want to create custom bar for displaying some progress, that must look something like this:

enter image description here

So, as you can see each bar has it's own gradient background. I want to use UICollectionView for this. But problem is to create gradient background for each individual cell. So is it possible somehow create ONE basic gradient for whole UICollectionView, and then mask it, to be visible inside UICollectionViewCell?

Upvotes: 0

Views: 970

Answers (1)

Shankar BS
Shankar BS

Reputation: 8402

Okay, here is the example, background is the gradient layer with different colours are spread and above you can create a mask layer to appear only on the rectangular shapes, which gives the illusion of the different rectangular layers having different gradient, you can play with gradient to get your desired effect,

First you subclass the UIView or you can create directly, better you can create a subclass as I am doing in the example

obj-c

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if(self)
    {
        [self createGreadient];
    }
    return self;
}

//this create a grenadine with the rectangular mask layer
- (void)createGreadient
{
    UIColor *theColor = [UIColor redColor];//[[UIColor alloc] initWithRed:146.0/255.0 green:146.0/255.0 blue:146.0/255.0 alpha:1];
    CAGradientLayer *gradientLayer = [[CAGradientLayer alloc] init];
    gradientLayer.frame = self.bounds;

    //u can add your own colours to get your requirement
    gradientLayer.colors = [NSArray arrayWithObjects:
                            (id)[theColor CGColor],
                            (id)[[theColor colorWithAlphaComponent:0.7f] CGColor],
                            (id)[[theColor colorWithAlphaComponent:0.4f] CGColor],
                            (id)[[theColor colorWithAlphaComponent:0.3f] CGColor],
                            (id)[[theColor colorWithAlphaComponent:0.2f] CGColor],
                            (id)[[theColor colorWithAlphaComponent:0.1f] CGColor],
                            (id)[[UIColor clearColor] CGColor],nil];
    [self.layer addSublayer:gradientLayer];

    CAShapeLayer *layerMask = [[CAShapeLayer alloc] init];
    layerMask.frame = self.bounds;
    UIBezierPath *rectangularMaskPath = [self getRectangularMaskPathForCount:5];
    layerMask.path = rectangularMaskPath.CGPath;

    gradientLayer.mask = layerMask;

}

 //this creates rectangular path, u can adjust the rectangular and u can 
//pass different number of count as the progress proceeds 
- (UIBezierPath *)getRectangularMaskPathForCount:(NSInteger)rectCount
{
    UIBezierPath *path = [[UIBezierPath alloc] init];
    int i = 0;
    for(;i <= rectCount; i++)
    {
        UIBezierPath *aPath;
        CGRect aRect = CGRectMake(20+ (i * 20), 20, 10, 100); //set the rectangular position to your requirement
        aPath = [UIBezierPath bezierPathWithRect:aRect]; 
        [path appendPath:aPath];
    }
    return path;
}

swift version subclass the UIView and past the below code,

 override init (frame : CGRect) {
    super.init(frame : frame)
    createGreadient()
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}



func createGreadient()
{
    let  color:UIColor = UIColor.red
    let greadetLayer = CAGradientLayer.init()

    greadetLayer.frame = self.bounds
    greadetLayer.colors = [color.withAlphaComponent(0.8).cgColor,color.withAlphaComponent(0.7),color.withAlphaComponent(0.4).cgColor,color.withAlphaComponent(0.3).cgColor,color.withAlphaComponent(0.2),color.withAlphaComponent(0.1).cgColor]

    self.layer .addSublayer(greadetLayer)
    let rectangularMaskPath  = self.creatrRectangularPathWithCount(countRect: 5)
    let maskLayer:CAShapeLayer = CAShapeLayer()
    maskLayer.frame = self.bounds
    maskLayer.path = rectangularMaskPath.cgPath
    greadetLayer.mask = maskLayer

}


func creatrRectangularPathWithCount(countRect:NSInteger) -> UIBezierPath {
    let path : UIBezierPath = UIBezierPath()
    for i in 0..<countRect {
       let aPath = UIBezierPath.init(rect: CGRect(x: 20 + (i * 20), y:20, width: 10, height: 100))
        path.append(aPath)
    }
    return path
}

You can use the above view like below, in ViewController

 override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    let customView:CustomView = CustomView(frame: CGRect(x: 20, y: 20, width: 300, height: 300))
    self.view.addSubview(customView)

}

Upvotes: 2

Related Questions