Edit collectionView Cells in UICollectionView - swift

I am creating an app programitcally (on my first try). I have managed to create a collection view and on the click of the add button in the navigation bar a new cell appears. I want to be able to set all cells created to be editable (in other words show the delete button on the cells) when the edit button in the navigation bar is clicked. Currently no matter what I try whether I click on edit or not, nothing happens. I have tried hiding the UIImage of the button as well as the button by calling a function created in the cell class when the edit button is clicked and have also tried moving this function to the ViewController Class, app runs but code doesn't do what it is supposed to.
My Code:
class CollectionViewController: UICollectionViewController, UITextViewDelegate {
// decelrations of variables for use
let cell = ListCell()
let cellId = "cellId"
var numberOfLists = 0
var lists = [String]()
let secondVC = TableViewController()
// for learning purposes: codes sets up the view programitcally along with what is in scenedelagate
override func viewDidLoad() {
super.viewDidLoad()
setCollectionView()
}
//Function that will generate the collectionView
func setCollectionView() {
collectionView.register(ListCell.self, forCellWithReuseIdentifier: cellId)
collectionView.backgroundColor = .white
navigationItem.title = "Lists"
navigationController?.navigationBar.barTintColor = UIColor(white: 200/255, alpha: 1)
navigationController?.navigationBar.titleTextAttributes = [.foregroundColor: UIColor.white, .font: UIFont.boldSystemFont(ofSize: 20)]
navigationItem.leftBarButtonItem = editButtonItem
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addTapped))
collectionView.delegate = self //runs the delegate flow methods
collectionView.dataSource = self
}
// to do with enabling editing in CV - function tied to edit button
override func setEditing(_ editing: Bool, animated: Bool){
super.setEditing(editing, animated: animated)
if editing {
print ("Editing Mode Enabled")
//cell.showButton()
} else {
print ("Editing Mode Closed")
}
// reloads the view after code is performed
self.collectionView.reloadData()
}
// func when buttons are tapped to add a collection view
#objc func addTapped() {
print("This button should not crash")
numberOfLists += 1
navigationController?.pushViewController(secondVC, animated: true)
collectionView.reloadData()
}
}
// the following block of code has to do with the set up of the collectionView
extension CollectionViewController: UICollectionViewDelegateFlowLayout {
// this code should speficiy how many cells you are going to have in your collectionview
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return numberOfLists
}
// this code lets you reuse a cell
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath)-> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! ListCell
cell.deleteButton.setImage(UIImage.init(named: "delete"), for: .normal)
return cell
}
// this code sets the sizing of the cells
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: (view.frame.width / 2) - 16, height: 100)
}
// where to place the cell on the screen
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 8, left: 9, bottom: 8, right: 8)
}
// this function just checks to see if the cell is selected
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
navigationController?.pushViewController(secondVC, animated: true)
}
}
//this class sets up the collectionViewCell
class ListCell: UICollectionViewCell {
override init(frame: CGRect) {
super.init(frame: frame)
setupCell()
}
fileprivate func setupCell(){
let colors = cellRandomBackgroundColors()
self.backgroundColor = colors[0]
self.addSubview(listNameLabel)
roundCorner()
setCellShadow()
self.addSubview(deleteButton)
deleteButton.addTarget(self, action: #selector(deleteCell), for: .touchUpInside)
}
#objc func deleteCell() {
print ("this button works")
}
func showButton() {
deleteButton.isHidden = true
print ("this is supposed to work")
}
func roundCorner() {
self.contentView.layer.cornerRadius = 50.0
self.contentView.layer.masksToBounds = true
self.contentView.layer.borderWidth = 1.0
self.contentView.layer.borderColor = UIColor.clear.cgColor
}
func setCellShadow() {
self.layer.shadowColor = UIColor.black.cgColor
self.layer.shadowOffset = CGSize(width: 0, height: 1)
self.layer.shadowOpacity = 0.2
self.layer.shadowRadius = 1.0
self.layer.masksToBounds = false
self.layer.cornerRadius = 3
self.clipsToBounds = false
}
func cellRandomBackgroundColors() -> [UIColor] {
//Colors
let red = [#colorLiteral(red: 0.9654200673, green: 0.1590853035, blue: 0.2688751221, alpha: 1),#colorLiteral(red: 0.7559037805, green: 0.1139892414, blue: 0.1577021778, alpha: 1)]
let orangeRed = [#colorLiteral(red: 0.9338900447, green: 0.4315618277, blue: 0.2564975619, alpha: 1),#colorLiteral(red: 0.8518816233, green: 0.1738803983, blue: 0.01849062555, alpha: 1)]
let orange = [#colorLiteral(red: 0.9953531623, green: 0.54947716, blue: 0.1281470656, alpha: 1),#colorLiteral(red: 0.9409626126, green: 0.7209432721, blue: 0.1315650344, alpha: 1)]
let yellow = [#colorLiteral(red: 0.9409626126, green: 0.7209432721, blue: 0.1315650344, alpha: 1),#colorLiteral(red: 0.8931249976, green: 0.5340107679, blue: 0.08877573162, alpha: 1)]
let green = [#colorLiteral(red: 0.3796315193, green: 0.7958304286, blue: 0.2592983842, alpha: 1),#colorLiteral(red: 0.2060100436, green: 0.6006633639, blue: 0.09944178909, alpha: 1)]
let greenBlue = [#colorLiteral(red: 0.2761503458, green: 0.824685812, blue: 0.7065336704, alpha: 1),#colorLiteral(red: 0, green: 0.6422213912, blue: 0.568986237, alpha: 1)]
let kindaBlue = [#colorLiteral(red: 0.2494148612, green: 0.8105323911, blue: 0.8425348401, alpha: 1),#colorLiteral(red: 0, green: 0.6073564887, blue: 0.7661359906, alpha: 1)]
let skyBlue = [#colorLiteral(red: 0.3045541644, green: 0.6749247313, blue: 0.9517192245, alpha: 1),#colorLiteral(red: 0.008423916064, green: 0.4699558616, blue: 0.882807076, alpha: 1)]
let blue = [#colorLiteral(red: 0.1774400771, green: 0.466574192, blue: 0.8732826114, alpha: 1),#colorLiteral(red: 0.00491155684, green: 0.287129879, blue: 0.7411141396, alpha: 1)]
let bluePurple = [#colorLiteral(red: 0.4613699913, green: 0.3118675947, blue: 0.8906354308, alpha: 1),#colorLiteral(red: 0.3018293083, green: 0.1458326578, blue: 0.7334778905, alpha: 1)]
let purple = [#colorLiteral(red: 0.7080290914, green: 0.3073516488, blue: 0.8653779626, alpha: 1),#colorLiteral(red: 0.5031493902, green: 0.1100070402, blue: 0.6790940762, alpha: 1)]
let pink = [#colorLiteral(red: 0.9495453238, green: 0.4185881019, blue: 0.6859942079, alpha: 1),#colorLiteral(red: 0.8123683333, green: 0.1657164991, blue: 0.5003474355, alpha: 1)]
let colorsTable: [Int: [UIColor]] = [0: red, 1: orangeRed, 2: orange, 3: yellow, 4: green, 5: greenBlue, 6: kindaBlue, 7: skyBlue, 8: blue, 9: bluePurple, 10: bluePurple, 11: purple, 12: pink]
let randomColors = colorsTable.values.randomElement()
return randomColors!
}
let deleteButton: UIButton = {
let deleteButton = UIButton(frame: CGRect(x:2,y:2,width:70,height:30))
return deleteButton
}()
let listNameLabel: UILabel = {
let listLabel = UILabel(frame: CGRect(x:2,y:50,width:70,height:30))
listLabel.text = "Data entry on Second View"
listLabel.font = UIFont.boldSystemFont(ofSize: 12)
listLabel.backgroundColor = .green
listLabel.translatesAutoresizingMaskIntoConstraints = false
listLabel.tag = 1
return listLabel
}()
let iconImageView: UIImageView = {
let imageView = UIImageView()
imageView.image = UIImage(named: "Folder")
imageView.contentMode = .scaleAspectFit
return imageView
}()
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Edit Button on Cells that doesn't disappear

Related

Problem with gradient on the background of a table swift

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)
}

Problem addient gradients to a custom cell background swift

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.

collectionView Animates Color on Reload

Whenever collectionView reloads, firstColor and secondColor mixes for a moment then get back to how they should be. For some reason adding gradient caused that problem. without gradient and with only one color this problem does not occur.
Here is the video link to the problem. Video
extension PostSurveyViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.surveyColors.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: SurveyColorCollectionViewCell.identifier, for: indexPath) as? SurveyColorCollectionViewCell
cell!.setup(surveyViewModel.surveyColors[indexPath.row])
return cell!
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
collectionView.allowsMultipleSelection = false
for index in surveyViewModel.surveyColors.indices {
self.surveyViewModel.surveyColors[index].isSelected = false
}
self.surveyViewModel.surveyColors[indexPath.row].isSelected = true
self.collectionView.reloadData()
}
}
class SurveyColorCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var bigSquare: UIView!
let gradientLayer: CAGradientLayer = CAGradientLayer()
static let identifier = String(describing: SurveyColorCollectionViewCell.self)
override func awakeFromNib() {
super.awakeFromNib()
}
func setupGradient(_ survey: SurveyModel) {
gradientLayer.frame = bigSquare.bounds
bigSquare.layer.insertSublayer(gradientLayer, at: 0)
let topColor: CGColor = survey.firstColor.cgColor
let bottomColor: CGColor = survey.secondColor.cgColor
gradientLayer.colors = [topColor, bottomColor]
gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)
bigSquare.clipsToBounds = true
}
func setup(_ survey: SurveyModel) {
bigSquare.layer.borderWidth = 1
bigSquare.layer.borderColor = UIColor.systemGray.cgColor
bigSquare.layer.cornerRadius = 8
self.setupGradient(survey)
}
class SurveyViewModel {
var surveyColors: [SurveyModel] = []
func getSurveys() {
surveyColors = [
SurveyModel(firstColor: UIColor.white, secondColor: UIColor.white, isSelected: true),
SurveyModel(firstColor: UIColor(red: 255/255, green: 138/255, blue: 0/255, alpha: 1), secondColor: UIColor(red: 159/255, green: 0/255, blue: 73/255, alpha: 1), isSelected: false),
SurveyModel(firstColor: UIColor(red: 19/255, green: 146/255, blue: 299/255, alpha: 1), secondColor: UIColor(red: 123/255, green: 0/255, blue: 139/255, alpha: 1), isSelected: false),
SurveyModel(firstColor: UIColor(red: 68/255, green: 204/255, blue: 98/255, alpha: 1), secondColor: UIColor(red: 0/255, green: 88/255, blue: 139/255, alpha: 1), isSelected: false)
]
}
}
struct SurveyModel {
let firstColor: UIColor
let secondColor: UIColor
var isSelected: Bool
}

Make view with tableview as its subview a gradient color

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

How to pass data from UITableView to UIViewController without segue

I need to pass the title of Row in UITableView to my ViewController. I don't have VC in storyboard (I've created it by code). So I can't use segue.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath) as! UITableViewCell
cell.textLabel?.textColor = UIColor(red: 0, green: 122/255, blue: 1, alpha: 1)
cell.textLabel?.tintColor = UIColor(red: 0, green: 122/255, blue: 1, alpha: 1)
var titleOfFood = String()
if searching == true {
titleOfFood = searchedFoods[indexPath.row].title
cell.textLabel?.textColor = UIColor(red: 0, green: 122/255, blue: 1, alpha: 1)
print(titleOfFood)
} else {
titleOfFood = foods[indexPath.row].title
cell.textLabel?.textColor = UIColor(red: 0, green: 122/255, blue: 1, alpha: 1)
print(titleOfFood)
}
let controller = EatenFoodViewController()
let transitionDelegate = SPStorkTransitioningDelegate()
controller.transitioningDelegate = transitionDelegate
controller.modalPresentationStyle = .custom
//controller.delegate = self
transitionDelegate.customHeight = 620
transitionDelegate.showIndicator = false
self.present(controller, animated: true, completion: nil)
}
I need to pass titleOfFood to EatenFoodViewController
You don't need to have a segue to send data to the destination vc , you can simply do
controller.titleOfFood = arr[indexPath.row].title // assuming you have an array of models
OR
controller.titleOfFood = cell.textLabel!.text!
class EatenFoodViewController:UIViewController {
var titleOfFood = ""
}