iOS fade to black at top of UIImageView - ios

I have a UITableView where my cell backgroundView is a UIImageView. I would like top of each image to fade to black so I can overlay some white text.
I have looked at some answers like this, but none seem to be working.
In tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) I have tried:
var imageView = UIImageView(image: image)
var gradient: CAGradientLayer = CAGradientLayer()
gradient.frame = imageView.frame
gradient.colors = [UIColor.blackColor(), UIColor.clearColor()]
gradient.locations = [0.0, 0.1]
imageView.layer.insertSublayer(gradient, atIndex: 0)
cell!.backgroundView = imageView
But I see no gradient and no difference from when I remove the gradient code. Is my gradient sitting under the image?
If I replace the line imageView.layer.insertSublayer(gradient, atIndex: 0) with imageView.layer.mask = gradient then my cells are just blank and white (no image anymore).

In your gradient.colors you need to have array of CGColor, so:
gradient.colors = [UIColor.blackColor().CGColor, UIColor.clearColor().CGColor]

I forget how the layers array is ordered. However, you should just add your gradient layer on top of your image view's layer using addSubLayer, not insertSublayer:atIndex: You want the gradient layer on top of the other layer so that it's non-opaque parts cover the image view.

For Swift 3.0, some slight tweaks required:
let gradient: CAGradientLayer = CAGradientLayer()
gradient.frame = imageView.frame
gradient.colors = [UIColor.black.cgColor, UIColor.clear.cgColor]
gradient.locations = [0.0, 0.1]
imageView.layer.insertSublayer(gradient, at: 0)

Related

How to apply a gradient to a UIImageView using a UIImage as a mask

I have a UIImage inside a UIImageView. I want to overlay a gradient from right to left in the shape of the UIImage.
I can render the UIImage as a template and apply a tint to the UIImageView, but obviously that only has one colour rather than a gradient. I saw some stuff on here about using the UIImage as a mask but I couldn't figure it out. Anyone know how to do this?
There might be easier ways but if I got you right this could work for you:
// create image and image view
let image = UIImage(named: "yourImage")
let imageView = UIImageView(image: image)
// create the gradient
let gradient = CAGradientLayer()
gradient.colors = [
UIColor.red.cgColor,
UIColor.green.cgColor
]
gradient.startPoint = CGPoint(x: 1, y: 0.5)
gradient.endPoint = CGPoint(x: 0, y: 0.5)
gradient.frame = imageView.bounds
// add a mask to the gradient
let mask = CALayer()
mask.contents = image?.cgImage
mask.frame = gradient.bounds
gradient.mask = mask
// add the gradient as a sublayer to the image view's layer
imageView.layer.addSublayer(gradient)
Result:

Adding a gradient layer on top of a UIButton's backgroundImage

I've got a project with some buttons that are in a UIStackView. Each of the buttons has a backgroundImage. Everything renders as desired, but I'd like to put a gradient layer in front of the backgroundImage that's semi-transparent so the text on the button has a little more contrast.
I'm attempting to use this code in viewDidLoad to add a semi-transparent gradient on front of each UIButton's backgroundImage:
buttonArray = [buttonOne, buttonTwo, buttonThree, buttonFour]
let gradientLayer = CAGradientLayer()
gradientLayer.colors = [UIColor(white: 1.0, alpha: 0.5)]
// gradientLayer.colors = [UIColor(white: 1.0, alpha: 0.5).cgColor]
// gradientLayer.colors = [UIColor.orange]
// gradientLayer.colors = [UIColor.orange.cgColor]
buttonArray.forEach({$0.imageView?.layer.insertSublayer(gradientLayer, at: 0)})
As it stands, nothing gets added. I tried changing the color to something without a alpha value and changing the desired color to a .cgColor. No dice. Thank you for reading. I welcome your suggestions how to put a gradientLayer in front of a UIButton's backgroundImage.
I based my attempt off code found here
I think you have to specify more than one color, as well as the bounds of the layer:
let buttonArray = [buttonOne, buttonTwo, buttonThree, buttonFour]
for button in buttonArray {
let gradientLayer = CAGradientLayer()
gradientLayer.colors = [UIColor(white: 0.5, alpha: 0.5).cgColor, UIColor(white: 1.0, alpha: 0.5).cgColor]
gradientLayer.frame = (button?.bounds)!
button?.layer.insertSublayer(gradientLayer, at: 0)
}

How to add gradient to UIView as an extension

I am trying to add some gradient to a view in Xcode and for simplicity I tried to add my method as an extension to UIView:
extension UIView {
func applyGradient() {
let gradient = CAGradientLayer()
gradient.colors = [UIColor(hex: "F5FF8C").cgColor,
UIColor(hex: "F1F99D").cgColor,
UIColor(hex: "FDFFE0").cgColor]
gradient.locations = [0.0, 0.5, 1.0]
self.layer.insertSublayer(gradient, at: 0)
}
}
But apparently this doesn't work when I call it in my viewDidLoad:
self.myView.applyGradient()
Can someone point to me what am I doing wrong ?
In the question, you haven't set the frame at all. In the comment, your frame was not set correctly. This is the code that should work properly:
extension UIView {
func applyGradient() {
let gradient = CAGradientLayer()
gradient.colors = [UIColor.red.cgColor,
UIColor.green.cgColor,
UIColor.black.cgColor] // your colors go here
gradient.locations = [0.0, 0.5, 1.0]
gradient.frame = self.bounds
self.layer.insertSublayer(gradient, at: 0)
}
}
With your code:
With the modified code:
Explanation
gradient.frame.size = self.frame.size doesn't work, while gradient.frame = self.bounds does, because the frame attribute contains both the location and the size of the view, and even if you set the gradient's frame size, you do not specify the location of the gradient... So the gradient is never actually added to the view. By setting the frame attribute directly to the bounds of the view, you also add the location of the gradient in the view.

Add gradient color on border of View

I am using swift 2.2 .I have a view and i want to use gradient color on inner border sides of view.Please help me.I am using the following code.Here i attach the screenshot which i need view.
self.layer.borderWidth = 1
self.layer.borderColor = UIColor(white:0.1, alpha: 0.5).CGColor
try this code
#IBOutlet weak var gradientView: UIView!
gradientView.backgroundColor = UIColor.clearColor()
let gradient:CAGradientLayer = CAGradientLayer()
gradient.startPoint = CGPoint(x: 0.0, y: 1.0)
gradient.endPoint = CGPoint(x: 0.0, y: 0.0)
gradient.frame.size = self.gradientView.frame.size
gradient.colors = [UIColor.darkGrayColor().CGColor,UIColor.darkGrayColor().colorWithAlphaComponent(0).CGColor] //Or any colors
gradient.locations = [ 0.0, 1.0]
self.gradientView.layer.insertSublayer(gradient, atIndex: 0)
iPatel's answer would work, but if you want to use the gradient function rather than an image, you could simply place a view with a gradient fill behind a slightly smaller view that holds your content. As long as the smaller, front view is inset from the gradient view by the same distance on all sides then this will give the effect that you are looking for.
As per my suggestion use below code for achieve gradient color
self.layer.borderColor = UIColor(patternImage:UIImage(named: "myCorrectImgName.png")!).CGColor
Where "myCorrectImgName.png" is name of image that have gradient color or required image that you want.
Otherwise you will be find may examples from the Google for how to set gradient color.

CAGradientLayer of UIView in TableView not resizing to Autolayout

I have created a UIView in IB with tag: 6. I use it in tableView.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:UITableViewCell = tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell
// create background view
var backgroundView = cell.contentView.viewWithTag(6) as UIView!
backgroundView.layer.cornerRadius = 10
backgroundView.layer.masksToBounds = true
// create gradient layer
let gradient : CAGradientLayer = CAGradientLayer()
// create color array
let arrayColors: [AnyObject] = [
UIColor (red: 33/255, green: 33/255, blue: 39/255, alpha: 1).CGColor,
UIColor (red: 24/255, green: 24/255, blue: 28/255, alpha: 1).CGColor]
// set gradient frame bounds to match view bounds
gradient.frame = backgroundView.bounds
// set gradient's color array
gradient.colors = arrayColors
gradient.startPoint = CGPoint(x: 0.0, y: 0.0)
gradient.locations = [0.1, 0.9]
gradient.endPoint = CGPoint(x: 1, y: 1)
// replace base layer with gradient layer
backgroundView.layer.insertSublayer(gradient, atIndex: 0)
The problem is, while the backgroundView resize to Autolayout, the gradient layer does not, as I would expect per:
gradient.frame = backgroundView.bounds
I could not find any answers applicable to UIViews in a TableView cell.
Question: What is the correct code to force a layer applied to a UIView in TableView to resize with autolayout?
I think you can try to subclass UITableViewCell then make CAGradientLayer as its default layer.
Then its size should follow its equivalent view although I do not test it.
This is the answer you are looking for: https://stackoverflow.com/a/4111917/2831015
Subclass UIView and use it as your "backgroundView". By overriding the layer class to a CAGradientLayer then you don't need to add the gradient as a sublayer, and such your gradient will autoResize based on the parent.

Resources