change or remove my CAGradientLayer when button is disabled - ios

I'm using a CAGradientLayer as the background for my button.
cell.showOnMap.clipsToBounds = YES;
cell.showOnMap.layer.cornerRadius = 10.0f;
UIView *view2 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, cell.showOnMap.frame.size.width, cell.showOnMap.frame.size.height)];
CAGradientLayer *gradient2 = [CAGradientLayer layer];
gradient2.frame = view2.bounds;
gradient2.colors = [NSArray arrayWithObjects:(id)[[UIColor colorWithRed:0.00 green:0.66 blue:0.71 alpha:1.0] CGColor], (id)[[UIColor colorWithRed:0.18 green:0.27 blue:0.75 alpha:1.0] CGColor], nil];
[cell.showOnMap.layer insertSublayer:gradient2 atIndex:0];
[cell.showOnMap bringSubviewToFront:cell.showOnMap.imageView];
There are cases in which my button, showOnMap will be disabled. In this case, I would like the CAGradient layer to change from lightGrayColor to grayColor OR remove the layer altogether. Here's the enable/disable code.
if(entry.address == nil)
{ [cell.showOnMap setEnabled:NO];
cell.showOnMap.layer.sublayers = nil;
}
else
[cell.showOnMap setEnabled:YES];
So far I have tried putting the entire gradient code within the else portion, then placing the same code in the if(entry.address == nil) but with gray colors as the gradients. This didn't work; the button was always the initial blue gradient.
I also tried cell.showOnMap.layer.sublayers = nil; but this removes the text and button image I have, leaving only a background with rounded edges.
[[cell.showOnMap.layer.sublayers objectAtIndex:0] removeFromSuperlayer]; didn't produce any change and [[cell.showOnMap.layer.sublayers objectAtIndex:0] removeFromSuperview]; caused a crash
How can I reference my CAgradient layer and remove it when my button is disabled?

Create a gradientLayer property inside your cell. Then init your gradientLayer to this property. And then you can safely reference it later to either modify it or removeFromSuperlayer.

Related

IOS/Objective-C: Change tint of an image view

I would like to change the color of an image view when the user touches it. I don't need it to change a great deal. However, I would like it to change to a shade of blue. I found the following code to change the gradient but it is not having any effect. I don't need a gradient, actually, only a tint. Would appreciate any suggestions.
UIView *snapshot = [[UIImageView alloc] initWithImage:image];
snapshot.layer.masksToBounds = NO;
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.colors = #[(id)[UIColor redColor].CGColor, (id)[UIColor blackColor].CGColor];
[snapshot.layer insertSublayer:gradient atIndex:0];
An easy and non-intrusive way is to add a translucent overlay to your image view. This can then be shown and hidden as the button is pressed and released.
- (void)indicatedImageViewPressed:(UIImageView *)imageView on:(BOOL)on {
UIView *overlay = [imageView viewWithTag:1]; // See if already created
if (overlay == nil) {
overlay = [[UIView alloc] initWithFrame:imageView.bounds];
overlay.tag = 1; // Mark view to find it next time
overlay.backgroundColor = [UIColor colorWithRed:0.0 green:0.0 blue:1.0 alpha:0.3]; // Your color overlay goes here
[imageView addSubview:overlay];
}
overlay.hidden = !on;
}
You can try giving the UIImage a tint
UIImage *image = [[UIImage imageNamed:#"Your Image"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.tintColor = [UIColor clearColor]; // Or any color really you'd like would work
imageView.image = newImage;
And then changing that tint when the user touches the image using a tap gesture recognizer

iOS How to set a gradient color to UITextField cursor

How to set a gradient color to UITextField cursor? The effect is just like the picture below:
here is the picture
you can ask disigner for an one pix picture ,then do like as follows:
UIColor *collor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"one"]];
self.textfield.tintColor = collor;
To change UITextField Cursor color, you have set it as Tint Color of Type UIColor.
textField.tintColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"gradient"]];
Do this for all text fields in your app using the UITextField appearance proxy:
[[UITextField appearance] setTintColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"gradient"]]];
BONUS:
If you need to set gradient color for UIView:
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 50)];
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = view.bounds;
gradient.colors = #[(id)[UIColor whiteColor].CGColor, (id)[UIColor blackColor].CGColor];
[view.layer insertSublayer:gradient atIndex:0];

Highlighting table view cell will not highlight subviews of table view cell using objective-C

I had table view with customised cell. In each row of the table view cell, there is subview with gradient colour and each row's background colour is different from subview's colour.
when I tap or touch each table view cell, then it is only highlighting background of tableview cell and not highlighting the subview. All the cell contents are not highlighted with green colour.
I tried removing gradient layer of subview and added background colour to it, then all the cell contents are highlighting but with gradient layer it is not highlighting.
Also I need to save the status, whether it is highlighted or not, how can i achieve this?
Here is the screen shot,
in cellForRowAtIndexPath method
UIView *selection_color = [[UIView alloc] init];
selection_color.backgroundColor = [UIColor greenColor];
cell.selectedBackgroundView = selection_color;
UIView *view = [UIView alloc] init];
view.layer.cornerRadius = 10;
view.layer.masksToBounds = YES;
view.layer.borderColor = [[UIColor colorWithRed:197/255.0 green:197.0/255.0 blue:197.0/255.0 alpha:1.0] CGColor];
view.layer.borderWidth = 1.0f;
view.tag = 10;
[cell.contentView addSubview: view];
NSArray *gradient_colors = [NSArray arrayWithObjects:(id)[UIColor redColor].CGColor, (id)[UIColor whiteColor].CGColor, nil];
NSArray *gradient_locations = [NSArray arrayWithObjects:[NSNumber numberWithInt:0.0],[NSNumber numberWithInt:1.0], nil];
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.colors = gradient_colors;
gradientLayer.locations = gradient_locations;
gradientLayer.masksToBounds = YES;
gradientLayer.frame = view.layer.bounds;
[view.layer addSublayer:gradientLayer];
guide me to solve this issue.
You have to override the setHighlighted method in your custom tableview cell, and set the highlight on the subviews as well.
- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated {
[super setHighlighted:highlighted animated:animated];
self.customView.backgroundColor = [UIColor redColor];
}

How do I set UIImage bounds?

I am having some trouble setting the correct location of the image for a UIImageView, which I am adding as a subview to a UIButton. I start by creating the button and adding some sublayers:
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setFrame:bounds];
//add gradient background
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = button.bounds;
gradient.colors = [NSArray arrayWithObjects:(id)[UIColor colorWithRed:.5 green:.5 blue:.5 alpha:1.0].CGColor, (id)[[UIColor blackColor] CGColor], nil];
[button.layer insertSublayer:gradient atIndex:0];
//set green background
CALayer *layer = [CALayer layer];
layer.frame = CGRectInset(button.bounds, 5, 5);
layer.backgroundColor = [UIColor colorWithRed:.55 green:.8 blue:.5 alpha:1.0].CGColor;
[button.layer insertSublayer:layer above:gradient];
I then use two methods to set the image. The first (which I use if no image is saved) uses an image resource that is scaled to be the right size, and is part of the app bundle. I set this with the following code:
UIImageView *v = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"profile.png"]];
[v setBounds:CGRectInset(button.bounds, 8, 8)];
[button addSubview:v];
The trouble comes from when I use an image taken through the camera, and saved to the file system. I am setting this to the background using the following code:
//path is an NSString set the the documents location of the image.
UIImageView *v = [[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:path]];
[v setBounds:CGRectInset(button.bounds, 8, 8)];
[v setContentMode:UIViewContentModeScaleToFill];
[button addSubview:v];
The output to the screen now shows the image way offset from where it should be:
What am I doing wrong? How do I correctly scale/fit the image in its parent view? I have tried simply setting the button image, but nothing appeared (perhaps the image was behind the sublayers?).
Use -setFrame method to set the frame of imageview instead of bounds
[v setFrame:CGRectInset(button.bounds, 8, 8)];
Thus the code become
UIImageView *v = [[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:path]];
[v setFrame:CGRectInset(button.bounds, 8, 8)];
[v setContentMode:UIViewContentModeScaleToFill];
[button addSubview:v];

UIButton with GradientLayer obscures image and darkens gradient

I have an UIButton here where I'd like to have a gradient as the background below the image (symbol with transparent background), but I'm facing two different problems.
First of the CAGradientLayer seems to overlay on top of the image no matter how I try to add it, obscuring the image completely.
Secondly the gradient itself seems to be darkened a lot, like the button was disabled, which it isn't.
Here's my code:
self.backButton = [[UIButton alloc] initWithFrame:CGRectMake(15, 35, 28, 28)];
[backButton addTarget:self
action:#selector(goBack)
forControlEvents:UIControlEventTouchUpInside];
[backButton setBackgroundColor:[UIColor clearColor]];
CAGradientLayer *buttonGradient = [CAGradientLayer layer];
buttonGradient.frame = backButton.bounds;
buttonGradient.colors = [NSArray arrayWithObjects:
(id)[[UIColor colorWithRed:.0
green:.166
blue:.255
alpha:1] CGColor],
(id)[[UIColor colorWithRed:.0
green:.113
blue:.255
alpha:1] CGColor],
nil];
[buttonGradient setCornerRadius:backButton.frame.size.width / 2];
[backButton.layer insertSublayer:buttonGradient
atIndex:0];
[backButton setImage:[UIImage imageNamed:#"backarrow.png"]
forState:UIControlStateNormal];
[backButton setEnabled:NO];
[topbarView addSubview:backButton];
So I managed to get around this by doing a [button bringSubviewToFront:button.imageView] after adding the gradient. Seems that no matter what I do the new layer will add on top of the imageView, so I need to push that to the front afterwards.
Objective-C:
[button bringSubviewToFront:button.imageView]
Swift 4.1:
button.bringSubview(toFront:button.imageView!)
Alternatively, you can insert the gradient layer below the image view's layer
CAGradientLayer* gradient = [CAGradientLayer layer];
// ...
[button.layer insertSublayer:gradient below:button.imageView.layer];
SWIFT 3
Here goes an example: (Based on Neil answer)
let layer = CAGradientLayer()
layer.frame = CGRect(x: 0, y: 0, width: myButtonOutlet.layer.frame.size.width, height: myButtonOutlet..layer.frame.size.height)
layer.colors = [UIColor.white.cgColor, pixelColorReceta.cgColor]
layer.masksToBounds = true
layer.cornerRadius = myButtonOutlet.layer.cornerRadius
myButtonOutlet.layer.insertSublayer(layer, below: myButtonOutlet..imageView?.layer)
Happy coding :)
Swift 3
You can move the image above the gradient:
button.imageView?.layer.zPosition = 1
or insert the gradient under the image:
button.layer.insertSublayer(gradientLayer, below: button.imageView?.layer)

Resources