I have custom Collection View Cell which contains ImageViews and labels. I want to add gradient colour to the image view.
I tried all the possible solutions like adding mask and adding gradient to sublayer of the image. But nothing works, guide me in solving this issue
let gradientLayer = CAGradientLayer()
gradientLayer.frame = self.asanasImage.layer.bounds
gradientLayer.colors = [UIColor.clear.cgColor,UIColor.black.cgColor]
gradientLayer.locations = [0.7,1.2]
self.asanasImage.layer.addSublayer(gradientLayer)
Hie ! Trying setting the gradient for your imageView in the method
cellForItemAt(_ indexpath: IndexPath) method as its in a collection View Cell.
Use this method
func setGradientBackground(imageView: UIImageView, colorTop: UIColor, colorBottom: UIColor) {
let gradientLayer = CAGradientLayer()
gradientLayer.colors = [colorBottom.cgColor, colorTop.cgColor]
gradientLayer.startPoint = CGPoint(x: 0.5, y: 1.0)
gradientLayer.endPoint = CGPoint(x: 0.5, y: 0.0)
gradientLayer.locations = [0, 1]
gradientLayer.frame = self.view.bounds
imageView.layer.insertSublayer(gradientLayer, at: 0)
}
Finally inside the cellForItemAt(_ indexpath: IndexPath) set the gradient of the imageView like so
setGradientBackground(imageView: cell.your_image_View, colorTop: any_color, colorBottom: any_color)
Customise the method according to your needs and the colors you want for your gradient.
Hope i was able to help. If it works lemme know and vote up please ! Thank You :D
Related
i am developing simple UITableView with custom UITableViewCell with Xib file
i have added MainView and pin it to ContentView in order to add all my views inside MainView
as shown below
UITableViewCell layout
when i try to add CAGradientLayer to MainView it doesnt fit perfectly on mainView bounds as i show below
whats happening on simulator
i use this piece of code to add CAGradientLayer
override func awakeFromNib() {
super.awakeFromNib()
let gradient = CAGradientLayer()
mainView.layer.cornerRadius = 10
gradient.frame = mainView.frame
gradient.colors = [ColorCompatibility.gradEnd.cgColor, ColorCompatibility.gradStart.cgColor]
gradient.endPoint = CGPoint(x: 0.5, y: 1)
gradient.startPoint = CGPoint(x: 0.5, y: 0)
// gradient.cornerRadius = 20
gradient.shadowColor = ColorCompatibility.systemBackground.cgColor
gradient.shadowOpacity = 0.8
gradient.shadowOffset = .zero
gradient.shadowRadius = 5
gradient.shadowPath = UIBezierPath(roundedRect: mainView.layer.bounds, cornerRadius: 20).cgPath
gradient.shouldRasterize = true
gradient.rasterizationScale = UIScreen.main.scale
contentView.layer.insertSublayer(gradient, at: 0)
}
how can i fix this?
Two issues here. The first is that in awakeFromNib the cell (and its content view) most likely doesn't have the correct frame so you could use another life cycle hook where the frame is correct but then you would run into problems when the device is rotated so the cell frame changes at runtime.
I would suggest to update the gradient layers frame in layoutSublayers(of:). Let's assume you created a property for the layer called gradient:
override func layoutSublayers(of layer: CALayer) {
super.layoutSublayers(of: layer)
gradient.frame = mainView.bounds
}
i'm trying to apply gradient color on view and button, but i'm facing an issue that it is not applying on the entire frame of button and view as you can see in screenshot.I have used this code and giving my custom hex values for color,
func applyGradient(colours: [UIColor]) -> Void {
let gradient: CAGradientLayer = CAGradientLayer()
gradient.frame = self.bounds
gradient.colors = colours.map { $0.cgColor }
gradient.startPoint = CGPoint(x : 0.0, y : 0.5)
gradient.endPoint = CGPoint(x :1.0, y: 1.5)
self.layer.insertSublayer(gradient, at: 0)
}
and applying like this by calling this function,
self.headerView.applyGradient(colours: [UIColor.init(hexString: "54F3FF"),UIColor.init(hexString: "43D7FF") ,UIColor.init(hexString: "30B7FF")])
Now when i run the app and test it, it looks like this
How can i apply gradient to full frame of view and button? What is the mistake in my code?
Try this
override func viewDidLayoutSubviews() {
self.headerView.applyGradient(colours: [UIColor.init(hexString: "54F3FF"),UIColor.init(hexString: "43D7FF") ,UIColor.init(hexString: "30B7FF")])
}
Hope this helps
#Junaid Khan,
Try like below,
extension UIView {
func applyGradient(colours: [CGColor], startPoint: CGPoint, endPoint: CGPoint, frame: CGRect) -> Void {
let gradientLayer = CAGradientLayer()
gradientLayer.colors = colours
gradientLayer.startPoint = startPoint
gradientLayer.endPoint = endPoint
gradientLayer.frame = frame
layer.insertSublayer(gradientLayer, at: 0)
}
}
If you have using constraints then call like below on your constraints method,
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
yourView?.applyGradient(colours: [UIColor.red.cgColor, UIColor.yellow.cgColor], startPoint: CGPoint(x: 0, y: 1), endPoint: CGPoint(x: 1, y: 1), frame: (yourView?.bounds)!)
}
Hope it's save your time!
Note: You can convert or get RGB colours by using your hexa color value.
I have a label in a macOS project which when connected becomes an NSTextField. I want to make the text have a gradient overlay.
I have some code to do this with an iOS UIButton, but for this project I keep getting the error that NSView has no such thing called mask and I don't know what to mask it to
extension NSTextField {
func applyGradientText(colors: [CGColor]) {
let gradient = CAGradientLayer()
gradient.frame = bounds
gradient.startPoint = CGPoint(x: 0.0, y: 0.5)
gradient.endPoint = CGPoint(x: 1.0, y: 0.5)
gradient.colors = colors
layer?.insertSublayer(gradient, at: 0)
let overlayView = NSView(frame: bounds)
overlayView.layer?.insertSublayer(gradient, at: 0)
overlayView has nothing called mask, and I don't know what to mask to
overlayView.mask = SOMETHING
addSubview(overlayView)
}
}
You need to call wantsLayer = true on the NSTextField as it doesn't have a layer by default. Then just set layer?.mask = gradient and the label will show where gradient is CGColor.clear.
label.applyGradientText(colors: [CGColor.black, CGColor.clear])
extension NSTextField {
func applyGradientText(colors: [CGColor]) {
let gradient = CAGradientLayer()
gradient.frame = bounds
gradient.startPoint = CGPoint(x: 0.0, y: 0.5)
gradient.endPoint = CGPoint(x: 1.0, y: 0.5)
gradient.colors = colors
wantsLayer = true
layer?.mask = gradient
}
}
Does this do what you want?
I'm trying to add an UIImage to customise my tabBar just like I did with my navigationBar, but it seems not work.
First I create a CAGradientLayer and then I turn it into UIImage. Here is the code:
extension CALayer {
func createImageFromLayer() -> UIImage?{
frame = CGRect(x: 0, y: 0, width: 1000, height: 1000)
UIGraphicsBeginImageContext(frame.size)
guard let context = UIGraphicsGetCurrentContext() else {return nil}
render(in: context)
let output = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return output
}
}
class CustomTabBarController: UITabBarController {
let grad: CAGradientLayer = {
let gradient = CAGradientLayer()
gradient.colors = [UIColor.clear, UIColor.black]
gradient.locations = [0,1]
return gradient
}()
override func viewDidLoad() {
super.viewDidLoad()
let tabImage = grad.createImageFromLayer()
self.tabBar.isTranslucent = true
self.tabBar.backgroundImage = tabImage
self.tabBar.shadowImage = UIImage()
}
}
Setting an image for my navigationBar worked perfectly using this method:
navigationController?.navigationBar.setBackgroundImage(barImg, for: UIBarMetrics.default)
In this code barImg is UIImage created from a CAGradientLayer just like with tabBar. I've checked if tabImage is nil and it's not.
It seems like tabBar doesn't have a function like tabBar.setBackgroundImage like navigationBar. How do I go about doing this?
The only result I get is a completely clear background for my tabBar with no gradient added and I don't know what I'm missing here once tabBar.backgroundImage doesn't work.
Thank you for the answers.
At first, when you setup colors for a CAGradientLayer you should use CGColor objects only. So you need to change that line to
gradient.colors = [UIColor.clear.cgColor, UIColor.black.cgColor]
After that your tabImage won't be empty and become visible.
The last problem is that you always set your image size to 1000x1000 pixels. That's way too much. To fix that you can pass target frame size to createImageFromLayer as a parameter. Its signature will become something like this.
func createImageFromLayer(targetFrame: CGRect) -> UIImage?
In your case targetFrame is tabBar.bounds.
I wanted to Mix two colors shaded and divided equally.
(Ignore the buttons inside of it)
Also, I want to apply this functionality somewhere horizontally and somewhere vertically.
Thank you.
The way you are looking for is CAGradientLayer.
For Vertical
let gradientLayer = CAGradientLayer()
gradientLayer.frame = self.gradientView.bounds
gradientLayer.colors = [UIColor.red.cgColor, UIColor.blue.cgColor] //Add different color here
self.gradientView.layer.addSublayer(gradientLayer) //Add Layer in your View
For Horizontal simply set startPoint and endPoint with gradientLayer.
gradientLayer.startPoint = CGPoint(x: 0, y: 0.5)
gradientLayer.endPoint = CGPoint(x: 1, y: 0.5)