How I can make a gradient with three opposite points? - ios

I want to make a color picker just like in the picture, but I could not do the triangle, which has three points to show the gradient, White, Black and the selected color.
The black and white are always the same, but the color selected should vary according to the user selects in the circle, but do not know how to make a gradient opposite to those three points, and displays the image.
(Only objective c, please)
Hope, someone could help me. Thanks.
HSL Picker

Here is what you can try to create gradient with three colors:
Get the reference from your triangle edges that have the reference to the color they point to.
BOOL isHorizontal=YES;
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = self.bounds;
gradient.colors = [NSArray arrayWithObjects:(id)[self.startColor CGColor],(id)[self.midColor CGColor], (id)[self.endColor CGColor], nil];
gradient.endPoint = (self.isHorizontal) ? CGPointMake(1, 0) : CGPointMake(0, 1);
[self.layer insertSublayer:gradient atIndex:0];
If you want to change the gradient direction, play around with:
[gradient setStartPoint:CGPointMake(0.0, 0.5)];
[gradient setEndPoint:CGPointMake(1.0, 0.5)];

Related

Stuck in UIImageView masking multiple images

I am working on UIImageView masking. Where i want image background like below.
You can see the black effect at bottom on text "Himalaya Gel".
I want to add such effect every time i add image.
So if anybody know's the solution pls help.
Thanks in advance.
You can use a gradient on the UIImageView, any time you change the UIImage, the gradient will still stay.
- (void)addGradientToView:(UIView *)view
{
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = CGRectMake(0, view.frame.size.height * 0.8, view.frame.size.width, view.frame.size.height * 0.2);
gradient.colors = #[(id)[[UIColor clearColor] CGColor],
(id)[[UIColor blackColor] CGColor]];
[view.layer insertSublayer:gradient atIndex:0];
}
The gradient will only start on the bottom of the view (view.hieght * 0.8) with a clear color, and continue till the end will black gradient.

CAGradientLayer not draw the gradient correctly

I use CAShapeLayer to draw a circle and set it as the mask of CAGradientLayer, here is the code:
CAShapeLayer *circleShapeLayer = [CAShapelayer new];
// draw circle path code here...
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.colors = #[(__bridge id)[UIColor whiteColor].CGColor,
(__bridge id)[UIColor clearColor].CGColor];
// self here means a UIView
gradientLayer.mask = circleShapeLayer;
gradientLayer.frame = self.bounds;
[self.layer addSublayer:gradientLayer];
When I run the app, it will display a gradient circle, but the gradient is strange.
What I want is a circle that at start point, the color is white and at end point the color is clear color, it should look like this:
But the color of the circle in the Simulator screen is:
The color is symmetric.
I think the problem is that I do not set the gradientLayer.colors correctly, how can I fix it?
CAGradientLayer can not paint gradient along an arc. on the other hand, the mask layer's frame is too small than gradient layer's frame to see clear color
To Umair's response, it didn't make sense to me at first because even whiteColor or blackColor is being fetched by colorWithRed:green:blue:alpha but then I read this in the documentation:
When rendered, the colors are mapped to the output color space before being interpolated.
So maybe this is really it:
gradientLayer.colors = #[(__bridge id)[UIColor colorWithRed:1.0f green:1.0f blue:1.0f alpha:1.0f].CGColor,
(__bridge id)[UIColor colorWithRed:1.0f green:1.0f blue:1.0f alpha:0.0f].CGColor];
#J.Hunter's answer is correct in that CAGradientLayers cannot draw along an arc. This means that your drawn gradients will be limited to radial and linear. You are specifically looking to create an angled gradient, which I've attempted to do in the past as well.
Unfortunately, CAGradientLayer is bound to these limitations, and the best way I've found to create a masked angled gradient is to mask with a UIImage that contains an angled gradient. This won't be nearly as dynamic as drawing your own gradient, but it seems to be the best (possibly only) option at the moment.

CAGradientLayer cannot change color

I want a colored gradient to overlay my view. In a view controller, I have this code
- (void)viewDidLoad {
self.view.backgroundColor = [UIColor whiteColor];
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.frame = self.view.bounds;
gradientLayer.colors = [NSArray arrayWithObjects:(id)[UIColor redColor].CGColor, (id)[UIColor clearColor].CGColor, nil];
gradientLayer.startPoint = CGPointMake(0, 0);
gradientLayer.endPoint = CGPointMake(0, 1.0f);
self.view.layer.mask = gradientLayer;
}
But even though the first color is red, I only ever see a black gradient. How can I display a red gradient instead?
TLDR: Instead of setting the gradient as the layer mask, add the gradient layer as a sublayer of view.layer.
Layers use the layer mask mask to determine the alpha of their own content by using the alpha of the mask at each pixel, since your gradientLayer is fully opaque, the effect you were getting wasn't the one you were hoping for.
Layers are similar to views (views are actually wrappers for layers), you can add them as sublayers in a similar way that views are added as subviews.

Create gradient on UIImage for text

I am trying to replicate the gradient found on the bottom of these album artwork image views. It makes it very easy to read the text no matter what the background is.
How would I recreate this?
The gradient effect is known as a floor fade.
The gradient starts with 0.0 alpha black at the middle of the image, to about 0.2 alpha black at the bottom of the image.
You could add a CAGradientLayer to your image, along the lines of:
CAGradientLayer *bottomFade = [CAGradientLayer layer];
bottomFade.frame = CGRectMake(0.0, CGRectGetHeight(self.imageView.bounds), CGRectGetWidth(self.imageView.bounds), -(CGRectGetHeight(self.imageView.bounds) / 2.0));
bottomFade.startPoint = CGPointMake(0.5, 1.0);
bottomFade.endPoint = CGPointMake(0.5, 0.0);
bottomFade.colors = [NSArray arrayWithObjects:(id)[[UIColor colorWithWhite:0.0 alpha:0.0f] CGColor], (id)[[UIColor colorWithWhite:0.0 alpha:0.2f] CGColor], nil];
[image.layer addSublayer:bottomFade];

CAGradientLayer covers everything drawn in drawRect

I have the following code:
-(void)drawRect:(CGRect)rect
{
// gradient background
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = rect;
gradient.colors = [NSArray arrayWithObjects:(id) backgroundGradientTop.CGColor, (id) backgroundGradientBottom.CGColor, nil];
gradient.locations = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0f], [NSNumber numberWithFloat:0.7], nil];
[self.layer insertSublayer:gradient atIndex:0];
// line on top
[[UIColor redColor] set];
CGContextRef currentContext = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(currentContext, 5.0f);
CGContextMoveToPoint(currentContext, 0, 10.0f);
CGContextAddLineToPoint(currentContext, rect.size.width, 10.0f);
CGContextStrokePath(currentContext);
}
the line i'm trying to draw on top of the gradient is never shown. If i comment out the gradient layer it is there. Is there someway to draw both a gradient background and a line (or a few lines) on top? Maybe i shouldn't be mixing calayer and CG?
The line i'm trying to draw on top of the gradient is never shown. If i comment out the gradient layer it is there.
That's because sublayers appear on top of their parent layers. Your gradient is apparently opaque, and the same size as your view, so it covers up the view.
You can't mix CA and CG drawing this way. It would work better if you drew the gradient using CGContextDrawLinearGradient.

Resources