UIPickerView - gradient broken in iOS 8 - ios

Before iOS 8, able to set a gradient background to a UIPickerView so the spinner would show on top and behind it, a gradient background as shown here:
Here is the code for the above prior to iOS 8:
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = pickerView.bounds;
gradient.colors = [NSArray arrayWithObjects:
(id)[[UIColor blackColor] CGColor],
(id)[[UIColor darkGrayColor] CGColor],
(id)[[UIColor lightGrayColor] CGColor],
(id)[[UIColor whiteColor] CGColor],
(id)[[UIColor lightGrayColor] CGColor],
(id)[[UIColor darkGrayColor] CGColor],
(id)[[UIColor blackColor] CGColor],
nil];
[pickerView.layer insertSublayer:gradient atIndex:0];
Using the above code in iOS 8, here is what displays:
Both pickers still function, but as you can see, the UI is not acceptable.
Suggestions? Thanks in advance!

Okay, I found a work-around, but still open to other, better options. My solution is:
Make UIPickerView backgroundColor transparent
Place a UILabel behind the UIPickerView
Create my gradient as above and add it to the UILabel as a subLayer :atIndex 0
Here is the code sample:
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = colorPickerBackgroundLabel.bounds;
gradient.colors = [NSArray arrayWithObjects:
(id)[[UIColor blackColor] CGColor],
(id)[[UIColor darkGrayColor] CGColor],
(id)[[UIColor lightGrayColor] CGColor],
(id)[[UIColor whiteColor] CGColor],
(id)[[UIColor lightGrayColor] CGColor],
(id)[[UIColor darkGrayColor] CGColor],
(id)[[UIColor blackColor] CGColor],
nil];
[colorPickerBackgroundLabel.layer addSublayer:gradient];
Here is the finished screen area capture:

Related

Adding CAGradient layer but unable to get Gradient effect

Here i am using this code to give a gradient effect but not getting the effect at all.
CAGradientLayer *layer2 = [CAGradientLayer layer];
NSArray *gradientColors = [NSArray arrayWithObjects:(id)[self colorWithHexString:#"3eb79d"].CGColor,(id)[self colorWithHexString:#"3fb65c"].CGColor,(id)[self colorWithHexString:#"3cb7da"].CGColor, nil];
[layer2 setColors:gradientColors];
[layer2 setFrame:cell.userBackgroundView.layer.frame];
[cell.userBackgroundView.layer insertSublayer:layer2 atIndex:0];
cell.userBackgroundView.clipsToBounds = YES;
Try this
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame =cell.userBackgroundView.frame;
gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor clearColor] CGColor], (id)[[UIColor blackColor] CGColor], nil];
[cell.userBackgroundView.layer insertSublayer:gradient atIndex:0];
Try to change index of sublayer from 0 to -1
[cell.userBackgroundView.layer insertSublayer:layer2 atIndex:-1];
Make sure your userBackgroundView is not covered by another view.
Use
[layer2 setFrame:cell.userBackgroundView.bounds];
instead of
[layer2 setFrame:cell.userBackgroundView.layer.frame];
If you are using autoLayout, make sure to set the frame in viewDidAppear or viewDidLayOutSubviews

Gradient Layer over ImageView reuse

Within my 'cellForRowAtIndexPath' I have the following code to populate the image (async) and apply a custom gradient
This worked fine, until I added a custom colour per cell. What it's currently doing is recycling the previous colour rather than applying a new one - this is presumably due to the following line which will skip the gradient code once applied to each cell:
if(!cell.gradientMask){
However, if I comment this out, the colours work but the gradient on each cell will stack up as a new layer is added each time (see existing issue)
I presume I need to remove the gradientLayer on each iteration, is that the best approach or perhaps I need to subclass the UIImageView?
if (!cell.gradientMask) {
gradientMask = [CAGradientLayer layer];
gradientMask.frame = cell.eventImage.layer.bounds;
gradientMask.startPoint = CGPointMake(0.5, 0.2);
gradientMask.endPoint = CGPointMake(0.5, 1.0);
/* THIS COLOUR CHANGES FOR EACH CELL */
gradientMask.colors = [NSArray arrayWithObjects:
(id)[[UIColor colorWithRed:0.0f green:0.0f blue:1.0f alpha:0.0f] CGColor],
(id)[[UIColor colorWithRed:0.0f green:0.0f blue:1.0f alpha:1.0f] CGColor],nil];
[cell.eventImage.layer insertSublayer:gradientMask atIndex:0];
cell.gradientMask = gradientMask;
}
You need to set the colors outside the block which creates the gradientMask:
if (!cell.gradientMask) { //Operations that need to be carried out only ONCE are put inside this block
gradientMask = [CAGradientLayer layer];
gradientMask.frame = cell.eventImage.layer.bounds;
gradientMask.startPoint = CGPointMake(0.5, 0.2);
gradientMask.endPoint = CGPointMake(0.5, 1.0);
[cell.eventImage.layer insertSublayer:gradientMask atIndex:0];
cell.gradientMask = gradientMask;
}
//Operations that need to be carried out again and again are outside the block
if (condition1)
{
cell.gradientMask.colors = [NSArray arrayWithObjects:
(id)[[UIColor colorWithRed:0.0f green:0.0f blue:1.0f alpha:0.0f] CGColor],
(id)[[UIColor colorWithRed:0.0f green:0.0f blue:1.0f alpha:1.0f] CGColor],nil];
}
else
{
cell.gradientMask.colors = [NSArray arrayWithObjects:
(id)[[UIColor colorWithRed:0.0f green:1.0f blue:0.0f alpha:0.0f] CGColor],
(id)[[UIColor colorWithRed:0.0f green:1.0f blue:0.0f alpha:1.0f] CGColor],nil];
}

CAGradientLayer is going out of frame of UILabel

I am doing simple things. As I am learning to implement CAGradientLayer.
The gradient you see is of Label. I am using autoresizing(not Autolayout). Apart from this have no code written. Autoresizing is not a problem since I've not touched that.
CAGradientLayer *gradientLayer = [[CAGradientLayer alloc]init];
gradientLayer.frame = lblHolder.frame;
gradientLayer.colors = [NSArray arrayWithObjects:(id)[[UIColor redColor] CGColor], (id)[[UIColor greenColor] CGColor], nil];
[lblHolder.layer insertSublayer:gradientLayer atIndex:0];
Try to make the following change:
gradientLayer.frame = lblHolder.bounds;

Circular gradient color "Not linear" in UIView

I have an issue with the gradient color, I'm not able to make the gradient color appear as circular, it always appear like linear, i need the exact gradient in the following image:
PS: this is the code i use:
UIView *view = [[UIView alloc] initWithFrame:self.view.frame];
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = view.bounds;
gradient.startPoint = CGPointMake(0.0,0.4);
gradient.endPoint = CGPointMake(0.0,0.6);
view.layer.masksToBounds = YES;
gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor colorWithRed:153.0/255.0 green:204.0/255.0 blue:0.0/255.0 alpha:1.0] CGColor], (id)[[UIColor whiteColor] CGColor], nil];
[view.layer insertSublayer:gradient atIndex:0];
[self.view addSubview:view];
There is a CGContextDrawRadialGradient in CGContext. I hope it will help you

iOS UITableViewCell CornerRadius Constant

I am extending UITableView and overriding setBackgroundView to add a gradient to cell in a grouped style table view. All good so far...
In order to apply rounded corners to the cell, I set the cornerRadius to 10 which looks about right.
All is working well but I don't like the idea of hardcoding the cornerRadius. Is this constant somewhere in the Cocoa code base?
Example:
- (void) setBackgroundView:(UIView *)backgroundView{
NSLog(#"called setBackground");
NSLog(#"%f", backgroundView.layer.shadowRadius); //yields 0.00000
NSLog(#"%f", backgroundView.layer.cornerRadius); //yields 3.00000
CAGradientLayer *gradient = [CAGradientLayer layer];
[gradient setCornerRadius:10];
[gradient setMasksToBounds:YES];
[gradient setBorderWidth:0.8f];
[gradient setBorderColor:[[UIColor darkGrayColor] CGColor]];
gradient.frame = backgroundView.bounds;
gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor greenColor] CGColor], (id) [[UIColor colorWithRed:.05 green:.65 blue:.05 alpha:1] CGColor],(id)[[UIColor colorWithRed:.05 green:.65 blue:.05 alpha:1] CGColor], (id)[[UIColor colorWithRed:.05 green:.45 blue:.05 alpha:1] CGColor], nil];
gradient.locations = [NSArray arrayWithObjects: (id)[NSNumber numberWithFloat:0.10], (id)[NSNumber numberWithFloat:0.50], (id)[NSNumber numberWithFloat:0.50], (id)[NSNumber numberWithFloat:1.0], nil];
[backgroundView.layer insertSublayer:gradient atIndex:0];
[super setBackgroundView:backgroundView]; }

Resources