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.