Hi to get the value of your Meals arrangement, I recommend you to quickly and easily make a class with the static variables you need, to start you would need the Meals static arrangement and I recommend you a id or index value so you know where they position you will be updating or replacing.class ClaseStaticGuardar {
static var meals = Meal
static var nuevoMeal: Meal?
}
In your class Meal adds a variable that is called index or id or something to if, something that identifies each of the items you are going to have, if you modify any you will know exactly how to change the array. var name: String
var photo: UIImage? // Es un optional porque lo mismo la comida no tiene foto asignada
var rating: Int
var index: Int
Then in your MealTableViewController class for example by saving the items or in any other class you will call the meal arrangement this way:ClassStaticSave.mealsimport UIKit
import os.log
class MealTableViewController: UITableViewController {
// MARK: Properties
//static var meals = Meal
override func viewDidLoad() {
super.viewDidLoad()
// Use the edit button item provided by the table view controller.
navigationItem.leftBarButtonItem = editButtonItem
if let savedMeals = loadMeals() {
ClaseStaticGuardar.meals += savedMeals
}
else {
// Load the sample data.
loadSampleMeals()
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
print("viewWillAppear >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
tableView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
// Tenemos sólo una sección, así que devolvemos 1
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return ClaseStaticGuardar.meals.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Identificador que hemos elegido antes. Como iOS reutiliza las celdas para mejorar el rendimiento, es necesario indicar un identificador
let cellIdentifier = "MealTableViewCell"
// Hay que probar con el guard porque estamos haciendo un casting de un optional
guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? MealTableViewCell else {
fatalError("La celda no es del tipo MealTableViewCell.")
}
// Hay que obtener la comida correcta del array
let meal = ClaseStaticGuardar.meals[indexPath.row]
// Establecer los datos a mostrar en la vista
cell.nameLabel.text = meal.name
cell.photoImageView.image = meal.photo
cell.ratingControl.rating = meal.rating
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 to support editing the table view.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// Delete the row from the data source
ClaseStaticGuardar.meals.remove(at: indexPath.row)
saveMeals()
tableView.deleteRows(at: [indexPath], with: .fade)
} else if editingStyle == .insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
/*
// Override to support rearranging the table view.
override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {
}
*/
/*
// Override to support conditional rearranging of the table view.
override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the item to be re-orderable.
return true
}
*/
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
super.prepare(for: segue, sender: sender)
switch(segue.identifier ?? "") {
case "AddItem":
os_log("Adding a new meal.", log: OSLog.default, type: .debug)
case "ShowDetail":
guard let tabBarController = segue.destination as? UITabBarController else {
fatalError("Unexpected destination: \(segue.destination)")
}
// guard let mealDetailViewController = tabBarController.viewControllers?.first as? NameMealViewController else {
// fatalError("Couldn't instantiate NameMealViewController from tabbar")
// }
guard let selectedMealCell = sender as? MealTableViewCell else {
fatalError("Unexpected sender: \(String(describing: sender))")
}
guard let indexPath = tableView.indexPath(for: selectedMealCell) else {
fatalError("The selected cell is not being displayed by the table")
}
let selectedMeal = ClaseStaticGuardar.meals[indexPath.row]
for i in (tabBarController.viewControllers)!{
let nombre = i as? NameMealViewController
nombre?.meal = selectedMeal
}
// mealDetailViewController.meal = selectedMeal
default:
fatalError("Unexpected Segue Identifier; \(String(describing: segue.identifier))")
}
}
// MARK: Actions
@IBAction func unwindToMealList(sender: UIStoryboardSegue) {
if let sourceViewController = sender.source as? MealViewController, let meal = sourceViewController.meal {
if let selectedIndexPath = tableView.indexPathForSelectedRow {
// Update an existing meal.
ClaseStaticGuardar.meals[selectedIndexPath.row] = meal
tableView.reloadRows(at: [selectedIndexPath], with: .none)
}
else {
// Add a new meal.
let newIndexPath = IndexPath(row:
ClaseStaticGuardar.meals.count, section: 0)
ClaseStaticGuardar.meals.append(meal)
tableView.insertRows(at: [newIndexPath], with: .automatic)
}
// Save the meals.
saveMeals()
}
}
// MARK: Private methods
private func loadSampleMeals() {
// Cargar las imágenes de prueba
let photo1 = UIImage(named: "meal1")
let photo2 = UIImage(named: "meal2")
let photo3 = UIImage(named: "meal3")
guard let meal1 = Meal(name: "Ensalada Caprese", photo: photo1, rating: 4, index: 0) else {
fatalError("No se puede instanciar meal1")
}
guard let meal2 = Meal(name: "Pollo con patatas", photo: photo2, rating: 5, index: 1) else {
fatalError("No se puede instanciar meal2")
}
guard let meal3 = Meal(name: "Pasta con albóndigas", photo: photo3, rating: 3, index: 2) else {
fatalError("No se puede instanciar meal3")
}
// Una vez creadas correctamente, se insertan en el array
ClaseStaticGuardar.meals += [meal1, meal2, meal3]
}
private func saveMeals() {
let isSuccessfulSave = NSKeyedArchiver.archiveRootObject(ClaseStaticGuardar.meals, toFile: Meal.ArchiveURL.path)
if isSuccessfulSave {
os_log("Meals successfully saved.", log: OSLog.default, type: .debug)
} else {
os_log("Failed to save meals...", log: OSLog.default, type: .error)
}
}
private func loadMeals() -> [Meal]? {
return NSKeyedUnarchiver.unarchiveObject(withFile: Meal.ArchiveURL.path) as? [Meal]
}
}
Then in this way every time you update a new Meal update it local or in the new Meal variable or you could use another static meal arrangement that keeps changes and then replace it with the main one, there are several options.In your tabbarViewController class, for example, you can do na function to save, and from there validate or update the values of the meal arrangement. @IBAction func SaveTap(_ sender: Any) {
ClaseStaticGuardar.meals.remove(at: (ClaseStaticGuardar.nuevoMeal?.index)!)
ClaseStaticGuardar.meals.insert(ClaseStaticGuardar.nuevoMeal!, at: (ClaseStaticGuardar.nuevoMeal?.index)!)
}
It's just a couple of ideas that can help you, you need to obviously add validations or give it the logic of modifying or saving that you want, the important thing that explains is that you see that you can keep the states of the variables in the ClassStatic and use them anywhere in your code.Greetings.