I have a tableview with the cells and I want apply a custom gradient. I've searched here but nothing works with my code.
My part of the code where I try to add the gradient
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Menú Principal"
tableView.backgroundView?.aplicarDegradadoDeportes()
self.navigationItem.setHidesBackButton(true, animated: true)
}
This is my function for the gradient
func aplicarDegradadoDeportes() {
let colorInicio = UIColor(red: 255/255, green: 59/255, blue: 0/255, alpha: 1.0).cgColor
let colorFin = UIColor(red: 255/255, green: 255/255, blue: 0/255, alpha: 1.0).cgColor
let gradientLayer = CAGradientLayer()
gradientLayer.colors = [colorInicio, colorFin]
gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)
gradientLayer.frame = self.bounds
self.layer.insertSublayer(gradientLayer, at:0)
}
Please help
You could create a custom UITableViewCell subclass and override the layoutSubviews() function.
For example like this:
class GradientTableViewCell: UITableViewCell {
// Property to store the gradient layer
private var gradientLayer: CAGradientLayer?
override func layoutSubviews() {
super.layoutSubviews()
// Check if gradient layer already exists
if gradientLayer == nil {
// Set the colors for the gradient
let colorInicio = UIColor(red: 255/255, green: 59/255, blue: 0/255, alpha: 1.0).cgColor
let colorFin = UIColor(red: 255/255, green: 255/255, blue: 0/255, alpha: 1.0).cgColor
// Create the gradient layer and set its properties
gradientLayer = CAGradientLayer()
gradientLayer?.colors = [colorInicio, colorFin]
gradientLayer?.startPoint = CGPoint(x: 0.0, y: 0.5)
gradientLayer?.endPoint = CGPoint(x: 1.0, y: 0.5)
gradientLayer?.frame = self.bounds
// Add the gradient layer as a sublayer to the cell's content view
self.contentView.layer.insertSublayer(gradientLayer!, at:0)
}
}
}
In your controller you need the set the cell class to GradientTableViewCell:
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Menú Principal"
self.navigationItem.setHidesBackButton(true, animated: true)
// Set the cell class for the table view to be GradientTableViewCell
self.tableView.register(GradientTableViewCell.self, forCellReuseIdentifier: "Cell")
}
In the cellForRowAt function of your table data dequeue a GradientTableViewCell instead of UITableViewCell
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Dequeue a GradientTableViewCell instead of a UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! GradientTableViewCell
// Configure the cell as needed
return cell
}
Now you should be able to set the gradient to the background of the cells
The backgroundView property of UITableView is nil by default. So your aplicarDegradadoDeportes function is never actually called.
Set a view as the backgroundView then it should work.
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Menú Principal"
let background = UIView()
tableView.backgroundView = background
background.aplicarDegradadoDeportes()
self.navigationItem.setHidesBackButton(true, animated: true)
}
The only issue is that the tableView will update the size of backgroundView as needed but your additional layer may not automatically get resized to match.
One solution is to move the code to setup the background view in viewWillAppear or you can override viewDidLayoutSubviews and update the layer's frame.
The best solution is to create a custom UIView subclass that draws the gradient so it stays up to date as it is sized.
class GradientView: UIView {
var gradient: CALayer!
override func didMoveToSuperview() {
super.didMoveToSuperview()
if superview != nil {
let colorInicio = UIColor(red: 255/255, green: 59/255, blue: 0/255, alpha: 1.0).cgColor
let colorFin = UIColor(red: 255/255, green: 255/255, blue: 0/255, alpha: 1.0).cgColor
let gradientLayer = CAGradientLayer()
gradientLayer.colors = [colorInicio, colorFin]
gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)
gradientLayer.frame = self.bounds
self.layer.insertSublayer(gradientLayer, at:0)
gradient = gradientLayer
}
}
override var frame: CGRect {
didSet {
gradient?.frame = bounds
}
}
}
Then your view controller viewDidLoad becomes:
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Menú Principal"
let background = GradientView()
tableView.backgroundView = background
self.navigationItem.setHidesBackButton(true, animated: true)
}
Related
I've created a custom class to apply different gradients as you can see. But my problem is that I can't use it to add gradient to a custom cell
import UIKit
extension UIView {
// MARK: - Creamos funcion para poder aplicar degrado vertical 2 colores
func aplicarFondoDegradado() {
let colorArriba = UIColor(red: 255/255, green: 4/255, blue: 14/255, alpha: 1.0).cgColor
let colorAbajo = UIColor(red: 0/255, green: 0/255, blue: 0/255, alpha: 1.0).cgColor
let gradientLayer = CAGradientLayer()
gradientLayer.colors = [colorArriba, colorAbajo]
gradientLayer.locations = [0.0, 1.0]
gradientLayer.frame = self.bounds
self.layer.insertSublayer(gradientLayer, at:0)
}
func aplicarDegradadoCultural() {
let colorInicio = UIColor(red: 0/255, green: 56/255, blue: 255/255, alpha: 1.0).cgColor
let colorFin = UIColor(red: 125/255, green: 195/255, blue: 226/255, alpha: 1.0).cgColor
let gradientLayer = CAGradientLayer()
gradientLayer.colors = [colorInicio, colorFin]
gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5)
// Set end point.
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)
gradientLayer.frame = self.bounds
self.layer.insertSublayer(gradientLayer, at:0)
}
func aplicarDegradadoDeportes() {
let colorInicio = UIColor(red: 0/255, green: 56/255, blue: 255/255, alpha: 1.0).cgColor
let colorFin = UIColor(red: 125/255, green: 195/255, blue: 226/255, alpha: 1.0).cgColor
let gradientLayer = CAGradientLayer()
gradientLayer.colors = [colorInicio, colorFin]
gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)
gradientLayer.frame = self.bounds
self.layer.insertSublayer(gradientLayer, at:0)
}
}
And It works but my problem is that when I tried to apply to a dinamic cell the gradient it's not shown.
This is my code for the tableview controller which includes the custom cell controller:
import UIKit
class EventosCustomCellController: UITableViewCell {
#IBOutlet weak var imEvento: UIImageView!
#IBOutlet weak var txtNombreEvento: UILabel!
#IBOutlet weak var txtFechaEvento: UILabel!
#IBOutlet weak var txtEstadoEvento: UILabel!
}
class ListaEventosTableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Eventos"
}
// MARK: - Table view data source
override func viewWillAppear(_ animated: Bool) {
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return eventos.contarEventos()
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "prototipoCeldaEvento", for: indexPath) as! EventosCustomCellController
let evento = eventos.buscarEventoPorID(id: indexPath.row)
cell.layer.borderWidth = 1
cell.layer.borderColor = UIColor.black.cgColor
cell.imageView?.layer.cornerRadius = 30
cell.txtNombreEvento?.text = evento?.nombre
cell.txtFechaEvento?.text = evento?.fecha
cell.txtEstadoEvento?.text = evento?.tipo
//THE PROBLEM IS HERE THE GRADIENT IS NOT SHOWN
//THE PROBLEM IS HERE THE GRADIENT IS NOT SHOWN
if evento?.tipo == "deportivo"{
cell.aplicarDegradadoCultural()}
else if evento?.tipo == "cultural"{
cell.aplicarFondoDegradado() }
else{
cell.aplicarDegradadoDeportes()}
cell.layer.masksToBounds = true
cell.layer.cornerRadius = 10
cell.imEvento.loadFrom(URLAddress: (evento?.imagenes![0])!)
cell.imEvento.layer.cornerRadius = 25
cell.imEvento.clipsToBounds = true
cell.imEvento.layer.borderWidth = 3
cell.imEvento.layer.borderColor = UIColor.white.cgColor
return cell
}
// Override to support conditional editing of the table view.
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return true
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let celdaPulsada = tableView.indexPathForSelectedRow?.row
eventos.devolverCeldaPulsada (id: celdaPulsada!)
}}
You're doing a couple things wrong -- and, you'll find it much easier to use a custom "GradientView"
Cells are reused... with your extension UIView approach, you are inserting another gradient layer every time the cell is used.
Also, you're not guaranteed to have the correct frame at that point.
Here is a very simple, basic custom "GradientView":
class GradientView: UIView {
var gradientLayer: CAGradientLayer!
override class var layerClass: AnyClass {
return CAGradientLayer.self
}
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
func commonInit() -> Void {
gradientLayer = self.layer as? CAGradientLayer
}
}
Add a UIView to your cell's Content View in Storyboard, behind all of the labels, and constrain it to all 4 sides.
Then, assign its Custom Class to GradientView, and connect it to your cell class just like the labels:
#IBOutlet weak var gradientView: GradientView!
Then, delete your extension UIView and move those gradient funcs to your cell, so it looks like this:
class EventosCustomCellController: UITableViewCell {
#IBOutlet weak var imEvento: UILabel!
#IBOutlet weak var txtNombreEvento: UILabel!
#IBOutlet weak var txtFechaEvento: UILabel!
#IBOutlet weak var txtEstadoEvento: UILabel!
#IBOutlet weak var gradientView: GradientView!
func aplicarFondoDegradado() {
let colorArriba = UIColor(red: 255/255, green: 4/255, blue: 14/255, alpha: 1.0).cgColor
let colorAbajo = UIColor(red: 0/255, green: 0/255, blue: 0/255, alpha: 1.0).cgColor
gradientView.gradientLayer.colors = [colorArriba, colorAbajo]
gradientView.gradientLayer.locations = [0.0, 1.0]
// start/end points
gradientView.gradientLayer.startPoint = CGPoint(x: 0.5, y: 0.0)
gradientView.gradientLayer.endPoint = CGPoint(x: 0.5, y: 1.0)
}
func aplicarDegradadoCultural() {
let colorInicio = UIColor(red: 0/255, green: 56/255, blue: 255/255, alpha: 1.0).cgColor
let colorFin = UIColor(red: 125/255, green: 195/255, blue: 226/255, alpha: 1.0).cgColor
gradientView.gradientLayer.colors = [colorInicio, colorFin]
// start/end points
gradientView.gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5)
gradientView.gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)
}
func aplicarDegradadoDeportes() {
let colorInicio = UIColor(red: 0/255, green: 56/255, blue: 255/255, alpha: 1.0).cgColor
let colorFin = UIColor(red: 125/255, green: 195/255, blue: 226/255, alpha: 1.0).cgColor
gradientView.gradientLayer.colors = [colorInicio, colorFin]
// start/end points
gradientView.gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5)
gradientView.gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)
}
}
Now you can keep this in cellForRowAt:
if evento?.tipo == "deportivo" {
cell.aplicarDegradadoCultural()
}
else if evento?.tipo == "cultural" {
cell.aplicarFondoDegradado()
}
else {
cell.aplicarDegradadoDeportes()
}
and your cell's will set the gradient properties and size automatically.
I can make the view a background gradient without the tableview. When I add the tableview, I can either have the gradient view without the tableview cells visible or the tableview cells are visible with a white background. I cannot present the tableview with the cells visible and the gradient visible "underneath" it as the background.
override func viewDidLoad() {
super.viewDidLoad()
configureTableView()
setGradientBackground()
}
func setGradientBackground() {
let colorTop = UIColor(red: 83/255, green: 187/255, blue: 204/255, alpha: 1.0).cgColor
let colorBottom = UIColor(red: 64/255, green: 109/255, blue: 164/255, alpha: 1.0).cgColor
let gradientLayer = CAGradientLayer()
gradientLayer.colors = [colorTop, colorBottom]
gradientLayer.locations = [0.0, 1.0]
gradientLayer.frame = self.view.bounds
tableView.layer.insertSublayer(gradientLayer, at:0)
}
private func configureTableView() {
tableView.register(NavigationMenuTableViewCell.self, forCellReuseIdentifier: "menu")
tableView.delegate = self
tableView.dataSource = self
tableView.separatorStyle = .none
view.addSubview(tableView)
tableView.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height)
}
class NavigationMenuTableViewCell: UITableViewCell {
private let label = UILabel()
func setup(_ buttonName: String) {
label.text = buttonName
label.font = UIFont.systemFont(ofSize: 14)
label.layer.cornerRadius = 6
label.clipsToBounds = true
label.textColor = .white
label.textAlignment = .center
label.backgroundColor = UIColor.init(displayP3Red: 50/255, green: 96/255, blue: 149/255, alpha: 1)
contentView.addSubview(label)
label.frame = CGRect(x: 20, y: 3, width: contentView.frame.width - 40, height: contentView.frame.height - 6)
}
}
You should create a separate view and set it as backgroundView for tableView.
In my case with collectionView it helped.
final class ViewController: UIViewController {
#IBOutlet weak var collectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
collectionView.dataSource = self
setGradientBackground()
}
private func setGradientBackground() {
let colorTop = UIColor(red: 83/255, green: 187/255, blue: 204/255, alpha: 1.0).cgColor
let colorBottom = UIColor(red: 64/255, green: 109/255, blue: 164/255, alpha: 1.0).cgColor
let gradientLayer = CAGradientLayer()
gradientLayer.colors = [colorTop, colorBottom]
gradientLayer.locations = [0.0, 1.0]
gradientLayer.frame = self.view.bounds
let backgroundView = UIView(frame: collectionView.bounds)
backgroundView.layer.insertSublayer(gradientLayer, at: .zero)
collectionView.backgroundView = backgroundView
}
}
extension ViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 100
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath)
cell.backgroundColor = .white
return cell
}
}
Result
I have added two views inside a stack view. I am having that stack view inside my tableViewCell. Now my stackView is placed in the centre of the content view with width and height. I want to apply gradient color inside my view which is inside my stackView .
Just look at the view below In this case I am giving view a background colour of red and green which I don't want. I want to apply gradient of four colours to this views.
enter image description here
Here is the code of a simple progress bar that I have written in Swift:
import Foundation
import Cocoa
public class GradientProgressView : NSView
{
// MARK: - Fields
private let bgLayer = CAShapeLayer()
private var progressLayer = CAShapeLayer()
private var gradientLayer = CAGradientLayer()
private var blockLayer = CAShapeLayer()
private var mValue: CGFloat = 0.0
// MARK: - Properties
public var colors: [NSColor] = [NSColor.systemGreen, NSColor.systemYellow, NSColor.sytemRed]
public var value: CGFloat
{
set
{
self.mValue = newValue
if self.mValue > 1.0
{
self.mValue = 1.0
}
if self.mValue < 0.0 || self.mValue.isNaN || self.mValue.isInfinite
{
self.mValue = 0.0
}
self.progressLayer.strokeEnd = self.mValue
}
get
{
return self.mValue
}
}
// MARK: - Overrides
public override func layout()
{
super.layout()
self.initialize()
}
// MARK: - Helper
fileprivate func initialize()
{
self.wantsLayer = true
self.layer?.masksToBounds = true // Optional
self.layer?.cornerRadius = self.bounds.height / 2.0 // Optional
self.bgLayer.removeFromSuperlayer()
self.bgLayer.contentsScale = NSScreen.scale
self.bgLayer.fillColor = NSColor.separatorColor.cgColor
self.bgLayer.path = NSBezierPath(rect: self.bounds).cgPath
self.layer?.addSublayer(self.bgLayer)
self.blockLayer.removeAllAnimations()
self.blockLayer.removeFromSuperlayer()
let path = NSBezierPath()
path.move(to: CGPoint(x: self.bounds.height / 2.0, y: self.bounds.height / 2.0))
path.line(to: CGPoint(x: self.bounds.width - self.bounds.height / 2.0, y: self.bounds.height / 2.0))
self.progressLayer.path = path.cgPath
self.progressLayer.strokeColor = NSColor.black.cgColor
self.progressLayer.fillColor = nil
self.progressLayer.lineWidth = self.bounds.height
self.progressLayer.lineCap = .round
self.progressLayer.strokeStart = 0.0
self.progressLayer.strokeEnd = 0.0
self.progressLayer.contentsScale = NSScreen.scale
self.gradientLayer.removeAllAnimations()
self.gradientLayer.removeFromSuperlayer()
self.gradientLayer.contentsScale = NSScreen.scale
self.gradientLayer.colors = self.colors.map({ $0.cgColor })
self.gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5)
self.gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)
self.gradientLayer.mask = self.progressLayer
self.gradientLayer.frame = self.bounds
self.gradientLayer.contentsScale = NSScreen.scale
self.layer?.addSublayer(self.gradientLayer)
}
}
This progress bar supports multiple colors.
Simply replace your progress bar logic with the one I posted above (or add the logic for the triangle that is shown below the progress bar).
Preview:
Create GradientLayer on your tableViewCell(collectionViewCell)
1. Create CAGradientLayer Instance on your tableViewCell
class MyCell: UITableViewCell {
let gradientLayer = CAGradientLayer()
}
2. Set the layer frame to view's bounds from layoutSublayers(of:)
If you set your layer's frame some other place, frame becomes weird.
class MyCell: UITableViewCell {
let gradientLayer = CAGradientLayer()
// Setting it from layoutSubViews also fine.
override func layoutSublayers(of layer: CALayer) {
super.layoutSublayers(of: self.layer)
gradientLayer.frame = yourView.bounds
}
}
3. Add GradientLayer on the View.
Here is my UIView extension for adding gradient layer.
extension UIView {
func addGradient(with layer: CAGradientLayer, gradientFrame: CGRect? = nil, colorSet: [UIColor],
locations: [Double], startEndPoints: (CGPoint, CGPoint)? = nil) {
layer.frame = gradientFrame ?? self.bounds
layer.frame.origin = .zero
let layerColorSet = colorSet.map { $0.cgColor }
let layerLocations = locations.map { $0 as NSNumber }
layer.colors = layerColorSet
layer.locations = layerLocations
if let startEndPoints = startEndPoints {
layer.startPoint = startEndPoints.0
layer.endPoint = startEndPoints.1
}
self.layer.insertSublayer(layer, above: self.layer)
}
}
* Option 1 - Add it from layoutSublayers(of:)
class MyCell: UITableViewCell {
let gradientLayer = CAGradientLayer()
override func layoutSublayers(of layer: CALayer) {
super.layoutSublayers(of: self.layer)
gradientLayer.frame = yourView.bounds
let colorSet = [UIColor(red: 255/255, green: 255/255, blue: 255/255, alpha: 1.0),
UIColor(red: 0/255, green: 0/255, blue: 0/255, alpha: 1.0)]
let location = [0.2, 1.0]
yourView.addGradient(with: gradientLayer, colorSet: colorSet, locations: location)
}
}
* Option 2 - Add it from cellForRowAt
For example, if we have cellForRowAt and like this,
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "yourCellId", for: indexPath) as? MyCell {
cell.configureCell(content: someItems[indexPath.row])
}
return UITableViewCell()
}
Now, we can handle gradientLayer from configureCell(content:).
class MyCell: UITableViewCell {
let gradientLayer = CAGradientLayer()
func configureCell(content: YourType) {
let colorSet = [UIColor(red: 255/255, green: 255/255, blue: 255/255, alpha: 1.0),
UIColor(red: 0/255, green: 0/255, blue: 0/255, alpha: 1.0)]
let location = [0.2, 1.0]
yourView.addGradient(with: gradientLayer, colorSet: colorSet, locations: location)
}
override func layoutSublayers(of layer: CALayer) {
super.layoutSublayers(of: self.layer)
gradientLayer.frame = yourView.bounds
}
}
import UIKit
class MainVC: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
func backgroundcolor(){
let newLayer = CAGradientLayer()
newLayer.colors = [UIColor.init(red: 0.2705882353, green: 0.4823529412, blue: 0.6156862745, alpha: 1).cgColor,UIColor.init(red: 0.6588235294, green: 0.8549019608, blue: 0.862745098, alpha: 1).cgColor]
newLayer.frame = view.frame
view.layer.addSublayer(newLayer)
}
}
In your viewDidLayoutSubviews, call your function. Any changes related to layout should be done in viewDidLayoutSubviews
import UIKit
class MainVC: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
backgroundColor()
}
func backgroundcolor(){
let newLayer = CAGradientLayer()
newLayer.colors = [UIColor.init(red: 0.2705882353, green: 0.4823529412, blue: 0.6156862745, alpha: 1).cgColor,UIColor.init(red: 0.6588235294, green: 0.8549019608, blue: 0.862745098, alpha: 1).cgColor]
newLayer.frame = view.frame
self.view.layer.insertSublayer(newLayer, at: 0)
}
}
Try this
let gradientView = UIView()
gradientView.frame = view.bounds
let newLayer = CAGradientLayer()
newLayer.colors = [UIColor.init(red: 0.2705882353, green: 0.4823529412, blue: 0.6156862745, alpha: 1).cgColor,UIColor.init(red: 0.6588235294, green: 0.8549019608, blue: 0.862745098, alpha: 1).cgColor]
newLayer.frame = gradientView.bounds
gradientView.layer.addSublayer(newLayer)
self.view.addSubview(gradientView)
self.view.sendSubviewToBack(gradientView)
I have encountered a problem involving setting gradients for labels and buttons. I know this question has been asked a lot, but no answer has seemed to solve my problem. Here is the screen as I want it to look:
This is my code:
#IBOutlet weak var loginButton: UIButton!
#IBOutlet weak var signUpButton: UIButton!
#IBOutlet weak var logoLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
loginButton.backgroundColor = UIColor.clear
let loginButtonGradient = createBlueGreenGradient(from: loginButton.bounds)
self.view.layer.insertSublayer(loginButtonGradient, at: 0)
signUpButton.backgroundColor = UIColor.clear
let signUpButtonGradient = createBlueGreenGradient(from: signUpButton.bounds)
self.view.layer.insertSublayer(signUpButtonGradient, at: 0)
logoLabel.backgroundColor = UIColor.clear
let logoLabelGradient = createBlueGreenGradient(from: logoLabel.bounds)
self.view.layer.insertSublayer(logoLabelGradient, at: 0)
loginButton.layer.cornerRadius = 100
signUpButton.layer.cornerRadius = 100
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func createBlueGreenGradient(from bounds: CGRect) -> CAGradientLayer{
let topColor = UIColor(red: 84/255, green: 183/255, blue: 211/255, alpha: 1)
let bottomColor = UIColor(red: 119/255, green: 202/255, blue: 151/255, alpha: 1)
let gradientColors: [UIColor] = [topColor, bottomColor]
let gradientLocations: [NSNumber] = [0.0, 1.0]
let gradientLayer = CAGradientLayer()
gradientLayer.colors = gradientColors
gradientLayer.locations = gradientLocations
gradientLayer.frame = bounds
return gradientLayer
}
And this is the wrong result:
Somebody please help me. I'm not sure what I'm doing wrong.
There are lots of issue with your code.
Divide the color with Float number instead of Int means it should be 255.0 not 255.
Now for colors property of CAGradientLayer you need to set array of CGColor not array of UIColor.
Also set startPoint and endPoint property of CAGradientLayer to make horizontal gradient color.
Currently you are adding this GradientLayer in your self.view instead of its specific button.
Set the cornerRadius of your button on basis of its height not with some constant 100 also after setting cornerRadius you need to also set masksToBounds property of layer to true.
Now for your logo label, you cannot set textColor as Gradient color directly what you need to do is draw the desired gradient on a UIImage and then use that UIImage to set the color pattern for your Label check this SO reference for that.
After making all this changes your code should be like.
func createBlueGreenGradient(from bounds: CGRect) -> CAGradientLayer{
let topColor = UIColor(red: 84/255.0, green: 183/255.0, blue: 211/255.0, alpha: 1).cgColor
let bottomColor = UIColor(red: 119/255.0, green: 202/255.0, blue: 151/255.0, alpha: 1).cgColor
let gradientColors = [topColor, bottomColor]
let gradientLocations: [NSNumber] = [0.0, 1.0]
let gradientLayer = CAGradientLayer()
gradientLayer.colors = gradientColors
gradientLayer.locations = gradientLocations
//Set startPoint and endPoint property also
gradientLayer.startPoint = CGPoint(x: 0, y: 0)
gradientLayer.endPoint = CGPoint(x: 1, y: 0)
gradientLayer.frame = bounds
return gradientLayer
}
Now set gradientLayer in viewDidLoad this way.
override func viewDidLoad() {
super.viewDidLoad()
let loginButtonGradient = createBlueGreenGradient(from: loginButton.bounds)
self.loginButton.layer.insertSublayer(loginButtonGradient, at: 0)
let signUpButtonGradient = createBlueGreenGradient(from: signUpButton.bounds)
self.signUpButton.layer.insertSublayer(signUpButtonGradient, at: 0)
loginButton.layer.cornerRadius = loginButton.frame.size.height / 2
loginButton.layer.masksToBounds = true
signUpButton.layer.cornerRadius = signUpButton.frame.size.height / 2
signUpButton.layer.masksToBounds = true
}
Your method like this:
func createBlueGreenGradient(from bounds: CGRect) -> CAGradientLayer{
let topColor = UIColor(red: 84/255, green: 183/255, blue: 211/255, alpha: 1).cgColor
let bottomColor = UIColor(red: 119/255, green: 202/255, blue: 151/255, alpha: 1).cgColor
let gradientColors = [topColor, bottomColor]
let gradientLocations: [NSNumber] = [0.0, 1.0]
let gradientLayer = CAGradientLayer()
gradientLayer.colors = gradientColors
gradientLayer.locations = gradientLocations
gradientLayer.frame = bounds
return gradientLayer
}
Oh my goodness I had the same problem, but played around with it. This is caused because you didnt add .cgcolor. For example :
let topColor = UIColor(red: 84/255, green: 183/255, blue: 211/255, alpha: 1).cgColor
let bottomColor = UIColor(red: 119/255, green: 202/255, blue: 151/255, alpha: 1).cgColor
let gradientColors = [topColor, bottomColor]
Let me know if it works.