UIView Gradient using CAGradientLayer always blue - ios

I am trying to create a UIView with a dark gray gradient:
UIView *sectionSpacer = [[UIView alloc] init];
sectionSpacer.backgroundColor = [UIColor clearColor];
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = sectionSpacer.bounds;
gradient.colors = [NSArray arrayWithObjects:(id)[RGB(80, 83, 88) CGColor], (id)[RGB(69, 71, 73) CGColor], nil];
[sectionSpacer.layer addSublayer:gradient];
For some reason the gradient view is always blue even thought the RGB values are dark grays. Why is this?

If you just init the view without a frame, it'll default to CGRectZero, so your layer will also have 0 width and height, which is why you don't see it (the gradient you do see looks like a standard UITableView header that may come from elsewhere, I doubt that it is even the same view you're initializing in the code you've shown).

Related

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.

ios push view with gradient background shows overlap

I use a gradient background for my views. When I push a new view using a segue, old view slides left and new view slides in - BUT for a brief moment the old view is still visible in the background and then abruptly turns off before the new view is in completely. Overall this is not smooth.
I am using this piece of code to set the gradient background...
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = vc.view.bounds;
UIColor *startColor = [UIColor colorWithRed:0.5 green:0.75 blue:0.75 alpha:0.98];
UIColor *endColor = [UIColor colorWithRed:0.5 green:0.75 blue:0.75 alpha:0.10];
gradient.colors = [NSArray arrayWithObjects:(id)[startColor CGColor], (id)[endColor CGColor], nil];
[vc.view.layer insertSublayer:gradient atIndex:0];
vc.navigationController.navigationBar.barTintColor = startColor;
Any idea what I am doing wrong ? Sorry if I haven't furnished all the information.

Wrong color on CAGradient applied to UITextView

I'm creating an iOS7 app and I have an UITextView inside a UITableView cell with a CAGradient applied to it. If I use different colors from clearColor works fine, but if I use clearColor as one of the colors for the gradient it turns out to be gray...
This is my code. theContent is my UITextView.
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = theContent.bounds;
gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor clearColor] CGColor], (id)[[UIColor whiteColor] CGColor], nil];
[theContent.layer insertSublayer:gradient atIndex:100];
And this is the final (wrong) result...
How can I fix this to have a clearColor to whiteColor gradient???
it may help on you if you try to use
[UIColor colorWithWhite:1.f alpha:0.f];
instead of the clearColor for the white tone.

Gradient text in a UITextField

I'm using a CAGradientLayer to make a gradient background for a text field. It looks like this
Instead of the background I want to have the gradient on the text. How can I make gradient text in a UITextField?
The code I used to make the gradient in the image
pinkDarkOp = [UIColor colorWithRed:0.9f green:0.53f blue:0.69f alpha:1.0];
pinkLightOp = [UIColor colorWithRed:0.79f green:0.45f blue:0.57f alpha:1.0];
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = [[myTextField layer] bounds];
gradient.cornerRadius = 7;
gradient.colors = [NSArray arrayWithObjects:
(id)pinkDarkOp.CGColor,
(id)pinkLightOp.CGColor,
nil];
[[myTextField layer]addSublayer:gradient];
You can solve this by creating two layers:
First you create a layer which you fill with the gradient.
Then you create another layer containing the text.
Finally you use the second layer as a mask for masking the first layer. This is achieved by assigning the second layer to the mask property of the first layer.
If I look more specifically on your code example, I think that everything before the last line should be OK. But then you should replace the last line with something like this:
gradient.mask = myTextField.layer;
Perhaps you need to do some adjustments to myTextField as well (hard to say since its definition is not part of the listed code). It's important to understand that the text in the mask must be opaque but the rest of that layer must be fully transparent. Read about the "mask" property in the CALayer class reference:
https://developer.apple.com/library/ios/DOCUMENTATION/GraphicsImaging/Reference/CALayer_class/Introduction/Introduction.html#//apple_ref/occ/instp/CALayer/mask
Dislaimer: I have not had time to test the code. I leave that to you. But the general idea of masking one layer with another should be possible to use, so I am convinced that you can sort out the details by yourself.
i made somme changes in my codes
pinkDarkOp = [UIColor colorWithRed:0.9f green:0.53f blue:0.69f alpha:1.0];
pinkLightOp = [UIColor colorWithRed:0.79f green:0.45f blue:0.57f alpha:1.0];
gradient.frame = [[myTextField layer] bounds];
gradient.cornerRadius = 7;
gradient.colors = [NSArray arrayWithObjects:(id)pinkDarkOp.CGColor,
(id)[[UIColor clearColor] CGColor], nil];
gradient.mask=myTextField.layer;
the text is invisible now

How to resize a CAGradientLayer after rotation?

I'm adding a CAGradientLayer to a view. When the view is auto-resized (such as after a rotation) the gradient layer is not resized. Can the gradient be set to auto-resize the same as the view? Note also that I am using auto-layout constraints in the view.
Here's what I'm doing:
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.frame = CGRectMake(0.0, 0.0, frame.size.width, frame.size.height);
gradientLayer.colors = [NSArray arrayWithObjects:
(id)[[UIColor colorWithRed:255.0/255.0f green:255.0/255.0f blue:255.0/255.0f alpha:1.0f] CGColor],
(id)[[UIColor colorWithRed:233.0/255.0f green:233.0/255.0f blue:233.0/255.0f alpha:1.0f] CGColor], nil];
[self.layer insertSublayer:gradientLayer atIndex:0];
Here are two different ways to fix your problem.
Make gradientLayer an instance variable instead of a local variable. Then, override layoutSubviews in your view class to set the frame of the gradient layer:
- (void)layoutSubviews {
[super layoutSubviews];
_gradientLayer.frame = self.bounds;
}
Create a subclass of UIView named GradientView, and override its +layerClass method to return [CAGradientLayer class]. Use this view to draw your gradient instead of using a layer directly. Then set the gradient view's autoresizingMask (or add constraints to it if you are using auto layout). See this answer for an example.
Creating the GradientView class will also make the resizing behave correctly during rotation, so I recommend that solution.
I resize the layer's bounds manually by overriding the setFrame: method of the view:
-(void)setFrame:(CGRect)frame
{
[super setFrame:frame];
_gradientLayer.bounds = CGRectMake(0, 0, CGRectGetWidth(frame), CGRectGetHeight(frame));
}

Resources