Sorry for the late response. Here is my code, both the custom UITableViewCell I made and my TableViewController class. I don't know how to get the indexPath in the didChangeStatusColor method, and I can't figure out how to pass the cell to that function. I'm relatively new to Swift, so I'm sort of teaching myself right now. Thanks!
import UIKit
protocol ItemCellDelegate
{
func didChangeStatusColor();
}
class ItemTableViewCell: UITableViewCell
{
//MARK: Properties
@IBOutlet var itemName: UILabel!
@IBOutlet var itemDate: UILabel!
@IBOutlet var itemStatusColor: UILabel!
@IBOutlet var changeStatusColorFunc: UIButton!
var delegate: ItemCellDelegate?
@IBAction func changeStatusColorTapped(_ sender: UIButton)
{
let currentCell = self
delegate?.didChangeStatusColor()
}
override func awakeFromNib()
{
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool)
{
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
import UIKit
import os.log
class ItemTableViewController: UITableViewController, ItemCellDelegate
{
// MARK: Properties
var items = [Item]()
var date1 = Date.init()
var date2 = Date.init()
var date3 = Date.init()
// MARK: Actions
@IBAction func unwindToItemList(sender: UIStoryboardSegue)
{
if let sourceViewController = sender.source as? ItemEditViewController, let item = sourceViewController.item
{
if let selectedIndexPath = tableView.indexPathForSelectedRow
{
// Update an existing item
items[selectedIndexPath.row] = item
tableView.reloadRows(at: [selectedIndexPath], with: .none)
}
else
{
// Add a new item
let newIndexPath = IndexPath(row: items.count, section: 0)
items.append(item)
tableView.insertRows(at: [newIndexPath], with: .automatic)
}
// Save the items
saveItems()
}
}
func didChangeStatusColor()
{
print("didChangeStatusColor tapped!")
}
// MARK: Private Methods
private func loadSampleItems()
{
guard let item1 = Item.init(name: "Do the dishes", date: date1, statusColor: UIColor.blue, colorList: [UIColor.blue, UIColor.green, UIColor.yellow]) else
{
fatalError("Unable to instantiate item1")
}
guard let item2 = Item.init(name: "Feed the dogs", date: date2, statusColor: UIColor.yellow, colorList: []) else
{
fatalError("Unable to instantiate item2")
}
guard let item3 = Item.init(name: "Finish economics paper", date: date3, statusColor: UIColor.purple, colorList: [UIColor.orange, UIColor.green]) else
{
fatalError("Unable to instantiate item3")
}
items += [item1, item2, item3]
}
override func viewDidLoad()
{
super.viewDidLoad()
// Use the edit button item provided by the table view controller
navigationItem.leftBarButtonItem = editButtonItem
// Load any saved items, otherwise load sample data
if let savedItems = loadItems()
{
items += savedItems
}
else
{
// Load the sample items
loadSampleItems()
}
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int
{
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
// #warning Incomplete implementation, return the number of rows
return items.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
// Set the cell identifier to ItemTableViewCell
let cellIdentifier = "ItemTableViewCell"
guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? ItemTableViewCell else
{
fatalError("Unable to downcast the cell in cellForRowAt to ItemTableViewCell")
}
// Gets the appropriate item from the datasource (the array of items)
let item = items[indexPath.row]
// Now use that item to configure the ItemTableViewCell
cell.itemName.text = item.name
// set the tag for the changeStatusColor button
//cell.changeStatusColorFunc.tag = indexPath.row;
//cell.changeStatusColorFunc.addTarget
cell.delegate = self
// if the date is the empty flag, set the itemDate label to the empty string
if item.date == Date.init(timeIntervalSince1970: 0)
{
cell.itemDate.text = ""
}
else // otherwise, get the date in the new format and set it to the itemDate label
{
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = " MMM d"
let stringFromDate = dateFormatter.string(from: item.date)
cell.itemDate.text = stringFromDate
}
cell.itemStatusColor.backgroundColor = item.statusColor
//cell.itemStatusColor.backgroundColor = item.statusColor
// Configure the cell...
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: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath)
{
if editingStyle == .delete
{
// Delete the row from the data source
items.remove(at: indexPath.row)
saveItems()
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?)
{
super.prepare(for: segue, sender: sender)
switch(segue.identifier ?? "")
{
case "AddItem":
os_log("Adding a new item.", log: OSLog.default, type: .debug)
case "showDetail":
guard let itemDetailViewController = segue.destination as? ItemEditViewController else
{
fatalError("Unexpected destination: \(segue.destination)")
}
guard let selectedItemCell = sender as? ItemTableViewCell else
{
fatalError("Unexpected sender: \(segue.destination)")
}
guard let indexPath = tableView.indexPath(for: selectedItemCell) else
{
fatalError("The selected cell is not being displayed in the table.")
}
let selectedItem = items[indexPath.row]
itemDetailViewController.item = selectedItem
default:
fatalError("Unexpected segue identifier: \(String(describing: segue.identifier))")
}
}
// MARK: Private Methods
private func saveItems()
{
let isSuccessfulSave = NSKeyedArchiver.archiveRootObject(items, toFile: Item.ArchiveURL.path)
if isSuccessfulSave
{
os_log("Items saved successfully.", log: OSLog.default, type: .debug)
}
else
{
os_log("Failed to save meals", log: OSLog.default, type: .debug)
}
}
private func loadItems() -> [Item]?
{
return NSKeyedUnarchiver.unarchiveObject(withFile: Item.ArchiveURL.path) as? [Item]
}
}