How do you save new index location in persistentcontainer? - arrays

I have a tableview where I have added the ability to move the location of rows. I am able to use the "swapAt" function to update my array and it works fine. The problem is that when I close and re-open the app, the rows continue to show in their old IndexPath. How can I also update the index location in the PersistentContainer so that when I open the app, it is updated with the new IndexPath?
I tried calling the save method of the context but it does not work.
import UIKit
import CoreData
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet var tableView: UITableView!
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
var toDoList = [Item] ()
var count: Int {
toDoList.count
}
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addItem))
navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(editItem))
title = "Todo"
loadItem()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return toDoList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "customCell", for: indexPath)
cell.textLabel?.text = toDoList [indexPath.row].title
if toDoList[indexPath.row].checkmark == true {
cell.accessoryType = .checkmark }
else {
cell.accessoryType = .none
}
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if toDoList[indexPath.row].checkmark == false {
toDoList[indexPath.row].checkmark = true } else {
toDoList[indexPath.row].checkmark = false
}
tableView.reloadData()
saveItem()
}
func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
toDoList.swapAt(sourceIndexPath.row, destinationIndexPath.row)
saveItem()
}
#objc func addItem () {
let ac = UIAlertController(title: "Add new category", message: nil, preferredStyle: .alert)
var textField = UITextField()
let submitAction = UIAlertAction(title: "Add", style: .default) { (action) in
let newItem = Item(context: self.context)
newItem.title = textField.text
newItem.checkmark = false
newItem.order = Int64(self.count)
self.toDoList.append(newItem)
self.saveItem()
}
ac.addTextField { (alertTextField) in
alertTextField.placeholder = "Create new item"
textField = alertTextField
}
ac.addAction(submitAction)
present(ac, animated: true, completion: nil)
}
func saveItem () {
do {
try context.save()
} catch {
print("This is the \(error)")
}
self.tableView.reloadData()
}
func loadItem () {
let request: NSFetchRequest<Item> = Item.fetchRequest()
let sortRequest = NSSortDescriptor(key: "order", ascending: true)
request.sortDescriptors = [sortRequest]
do {
toDoList = try context.fetch(request)
} catch {
print("the error is \(error)")
}
tableView.reloadData()
}
#objc func editItem () {
if tableView.isEditing {
tableView.isEditing = false
} else {
tableView.isEditing = true
}}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
context.delete(toDoList[indexPath.row])
saveItem()
self.toDoList.remove(at: indexPath.row)
self.tableView.deleteRows(at: [indexPath], with: .automatic)
}
}
}

I would tackle this problem by having an index property in the Coredata entity; this index reflects the position of the element in the table view. In the swapAtFunction add the logic to switch the index properties of the two elements.
Then, when you fetch the entities, you add a predicate to your request, to sort the elements by the index property.
let fetchRequest = NSFetchRequest<EntityName>(entityName: "EntityName")
let sortDescripor = NSSortDescriptor(key: "index", ascending: true)
fetchRequest.sortDescriptors = [sortDescripor]
Then execute fetchRequest as you normally would, and assign the resulting array to the UICollectionView's Datasource.

Related

Why is my data not showing up in my TableView?

The data that I am retrieving from Firebase is not showing up in my table view, but it is showing up in my snapshot. What am I missing?
Here is my code:
import UIKit
import Firebase
import FirebaseDatabase
class NewConversationViewController: UITableViewController {
var users = [User]()
let cellId = "cellId"
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
navigationController?.navigationBar.shadowImage = UIImage()
tableView.delegate = self
tableView.dataSource = self
fetchUser()
tableView.isHidden = false
}
func fetchUser() {
Database.database().reference().child("users").observeSingleEvent(of: .value, with: { snapshot in
if let dictionary = snapshot.value as? [String: AnyObject] {
let user = User()
user.setValuesForKeys(dictionary)
self.users.append(user)
}
print(snapshot)
DispatchQueue.main.async {
self.tableView.reloadData()
}
}, withCancel: nil)
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return users.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
let user = users[indexPath.section]
cell.textLabel?.text = user.name
return cell
}
}

Sorting a TableView alphabetically in Swift 3

I have searched Stack Overflow well and truly with a variety of different options offered but none I can seem to get working.
I have an app which has a glossary of terms for NFL (e.g. offence/defence) etc. It comes from a JSON API and is stored locally. I would like to sort the data programmatically, so the terms are all listed in their respective sections ("A", "B", "C" etc.) alphabetically.
View Controller:
import UIKit
class GlossaryVC: UIViewController, UITableViewDelegate, UITableViewDataSource {
private let glossaryCellId = "GlossaryCell"
var glossarys = [Offence]()
var filteredGlossarys = [Offence]()
private var subCategorySet: Set<String> = []
private var glossarysDictionary: [String: [Offence]] = [:]
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var searchBar: UISearchBar!
#IBOutlet weak var noResultsView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
filteredGlossarys = glossarys
tableView.delegate = self
tableView.dataSource = self
tableView.backgroundColor = UIColor.clear
searchBar.delegate = self
noResultsView.isHidden = true
hideKeyboardWhenTappedAround()
}
override func viewDidAppear(_ animated: Bool) {
DataProvider.getData(with: .GLOSSARY_DATA_URL) { (letters) in
self.glossarys = letters.flatMap { $0.offences }
self.filteredGlossarys = self.glossarys
self.groupGlossarys()
}
}
func groupGlossarys() {
glossarysDictionary.removeAll()
subCategorySet.removeAll()
for glossary in filteredGlossarys {
subCategorySet.insert(glossary.glossaryLetter!)
}
for subCategory in subCategorySet {
glossarysDictionary[subCategory] = []
}
for glossary in filteredGlossarys {
var list = glossarysDictionary[glossary.glossaryLetter!]
list?.append(glossary)
glossarysDictionary[glossary.glossaryLetter!] = list
}
checkAndShowTableView()
}
func checkAndShowTableView() {
if subCategorySet.count > 0 {
tableView.isHidden = false
noResultsView.isHidden = true
tableView.reloadData()
} else {
tableView.isHidden = true
noResultsView.isHidden = false
}
}
func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
let header = view as! UITableViewHeaderFooterView
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 60
}
func numberOfSections(in tableView: UITableView) -> Int {
return subCategorySet.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
let subCategoryList = Array(subCategorySet)
return subCategoryList[section]
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let subCategoryList = Array(subCategorySet)
let glossaryList = glossarysDictionary[subCategoryList[section]]
return glossaryList!.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let glossaryCell = tableView.dequeueReusableCell(withIdentifier: glossaryCellId, for: indexPath) as? GlossaryCell else {
fatalError("Unable to dequeue contact cell")
}
let subCategoryList = Array(subCategorySet)
let glossaryList = glossarysDictionary[subCategoryList[indexPath.section]]
glossaryCell.configure(glossary:(glossaryList?[indexPath.row])!)
return glossaryCell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
cell.backgroundColor = UIColor.clear
cell.contentView.backgroundColor = UIColor.clear
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let viewGlossaryDetailsVC = segue.destination as? GlossaryDetailsVC,
let section = tableView.indexPathForSelectedRow?.section, let row = tableView.indexPathForSelectedRow?.row {
let subCategoryList = Array(subCategorySet)
let glossaryList = glossarysDictionary[subCategoryList[section]]
let glossarys = glossaryList?[row]
viewGlossaryDetailsVC.glossarys = glossarys
}
}
}
extension GlossaryVC: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if !searchText.isEmpty {
filteredGlossarys = glossarys.filter({ (glossary) -> Bool in
let glossaryTitleRange = glossary.glossaryTitle?.range(of: searchText, options: .caseInsensitive)
let glossaryDescriptionRange = glossary.glossaryDescription?.range(of: searchText, options: .caseInsensitive)
let glossaryKeywordsRange = glossary.glossaryKeywords?.range(of: searchText, options: .caseInsensitive)
return glossaryTitleRange != nil || glossaryDescriptionRange != nil || glossaryKeywordsRange != nil
})
} else {
filteredGlossarys = glossarys
}
groupGlossarys()
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
searchBar.resignFirstResponder()
}
}
I have so far tried the sorted(by: {}) method on the let subCategoryList = Array(subCategorySet) in the titleForHeaderInSection which does arrange the section headers alphabetically but the data doesn't change. So you end up having words beginning with "H" in the "A" subcategory.
Data is grouped based on a "letter" key in the database, e.g., so all "A" are grouped together, etc.
Any help would be appreciated, all I want to do is sort it alphabetically and I feel a little out of my depth.

Cannot assign to property: 'itemArray' is a get-only property

I am currently trying to implement a simple search function using UISearchBar and Core Data I am getting an error within this function "Cannot assign to property: "ItemArray" is a get-only property" If anyone can help with the error and also suggest another simple way to implement the search that would be really helpful.
func loadItems(with request: NSFetchRequest<Item>) {
let request : NSFetchRequest<Item> = Item.fetchRequest()
do {
itemArray = try context.fetch(request)
} catch {
print("Error fetching data from context")
}
tableView.reloadData()
}
}
Here is the whole file:
import UIKit
import CoreData
class TodoListViewController: UITableViewController {
var itemArray: [Item] { return Array(self.category.items!) as! [Item] }
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
var category: Category!
override func viewDidLoad() {
super.viewDidLoad()
print(FileManager.default.urls(for: .documentDirectory, in: .userDomainMask))
}
#IBOutlet weak var todoTableView: UITableView!
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return itemArray.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ToDoItemCell", for: indexPath)
let item = itemArray[indexPath.row]
cell.textLabel?.text = item.title
cell.accessoryType = item.done ? .checkmark : .none
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//print(itemArray[indexPath.row])
itemArray[indexPath.row].done = !itemArray[indexPath.row].done
saveItems()
tableView.deselectRow(at: indexPath, animated: true)
}
#IBAction func addButtonPressed(_ sender: UIBarButtonItem) {
var textField = UITextField()
let alert = UIAlertController(title: "Add New Todoey Item", message: "", preferredStyle: .alert)
let action = UIAlertAction(title: "Add Item", style: .default) { [weak self] (action) in
guard let self = self else { return }
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let newItem = Item(context: self.context)
newItem.title = textField.text!
self.category.addToItems(newItem)
self.saveItems()
}
alert.addTextField { (alertTextField) in
alertTextField.placeholder = "Create new item"
textField = alertTextField
print(alertTextField.text)
}
alert.addAction(action)
self.present(alert, animated: true, completion: nil)
}
func saveItems() {
do {
try context.save()
} catch {
print("Error saving context")
}
self.tableView.reloadData()
}
func loadItems(with request: NSFetchRequest<Item>) {
let request : NSFetchRequest<Item> = Item.fetchRequest()
do {
itemArray = try context.fetch(request)
} catch {
print("Error fetching data from context")
}
tableView.reloadData()
}
}
extension TodoListViewController: UISearchBarDelegate {
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
let request : NSFetchRequest<Item> = Item.fetchRequest()
request.predicate = NSPredicate(format: "title CONTAINS[cd] %#", searchBar.text!)
request.sortDescriptors = [NSSortDescriptor(key: "title", ascending: true)]
loadItems(with: request)
tableView.reloadData()
}
itemArray is declared as read-only property, that's exactly what the error says.
A solution is to declare the property as empty array
var itemArray = [Item]()
and call loadItems in viewDidLoad()
override func viewDidLoad() {
super.viewDidLoad()
loadItems()
print(FileManager.default.urls(for: .documentDirectory, in: .userDomainMask))
}
The parameter in loadItems is pointless, omit it.
func loadItems() { ... }
If you want to fetch the items for a specific Category add an appropriate NSPredicate in loadItems

How to save an array. So its the same after App restarts

I am wondering how to let my to-do-list be the same after the app is closed. In my code I am declaring an array right in the beginning and I want to know how I can save it updated for the user, after he restarted the App. I searched the web for some answers but only found old ideas about creating entities in storyboard. And I am pretty sure, that by now there has to be something more beautifully than adding it manually.
How can I save the array when it is getting updated, so it won't get lost after an app restart?
My Code:
import UIKit
var checklist = ["Item 1", "Item 2"]
class ChecklistViewController: BaseViewController, UITableViewDelegate, UITableViewDataSource{
var newChecklistItemString: String?
var alertInputTextField: UITextField?
#IBOutlet weak var myTableView: UITableView!
let mainStoryboard:UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
var selectedChecklist: [String] = []
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return (checklist.count)
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCell.CellStyle.default, reuseIdentifier: "cell")
cell.textLabel?.font = UIFont.boldSystemFont(ofSize: 18.0)
cell.textLabel?.text = checklist[indexPath.row]
if selectedChecklist.contains(checklist[indexPath.row]) {
cell.accessoryType = .checkmark
}
else{
cell.accessoryType = .none
}
return cell
}
// checkmarks when tapped
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark
selectedChecklist.append(checklist[indexPath.row])
tableView.deselectRow(at: indexPath, animated: true)
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
let value = checklist.remove(at: indexPath.row)
myTableView.reloadData()
}
}
override func viewDidAppear(_ animated: Bool) {
myTableView.reloadData()
}
override func viewDidLoad() {
super.viewDidLoad()
addSlideMenuButton()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func addNewObject(_ sender: Any) {
let alert = UIAlertController(title: "New Item", message: nil, preferredStyle: .alert)
alert.addTextField { (alertInputTextField) in
alertInputTextField.autocapitalizationType = .sentences
}
alert.addAction(UIAlertAction(title: "Cancel", style: .default, handler: { (action) in
self.dismiss(animated: true, completion: nil)
}))
alert.addAction(UIAlertAction(title: "Add", style: .default, handler: { (action) in
let textf = alert.textFields![0] as UITextField
if(textf.text != "")
{
checklist.append(textf.text!)
}
self.myTableView.reloadData()
}))
self.present(alert, animated: true, completion: nil)
}
}
For a simple string array use UserDefaults
Declare two methods to load and save data
func loadDefaults()
{
self.checklist = UserDefaults.standard.array(forKey: "checklist") as? [String] ?? []
}
func saveDefaults()
{
UserDefaults.standard.set(self.checklist, forKey: "checklist")
}
In viewDidLoad add
loadDefaults()
And right after adding and removing an item add
saveDefaults()
For more complex data other solutions like Core Data are preferable
Note:
Rather than always reloading the entire table view use the API to insert and delete single rows. The benefit is a nice animation.
In tableView:commit replace myTableView.reloadData() with
myTableView.deleteRows(at: [indexPath], with: .automatic)
and in the alert action replace the entire if expression with
if !textf.text!.isEmpty {
let indexPath = IndexPath(row: checklist.count, section: 0)
checklist.append(textf.text!)
myTableView.insertRows(at: [indexPath], with: .automatic)
}
And move the variable checklist into the class!
Find this solution:
// Use this code to fetch saved item list.
if let items = UserDefaults.standard.value(forKey: "ItemListArray") as? [String] {
print(items)
}
// Use this code to save your item list.
let itemList = ["Item 1", "Item 2", "Item 3", "Item 4"]
UserDefaults.standard.setValue(itemList, forKey: "ItemListArray")
// Use this code to remove item list
UserDefaults.standard.setValue(nil, forKey: "ItemListArray")
Check the code below:-
class ClassUserDefaults {
static let shared = ClassUserDefaults()
// MARK: - SETTER GETTER
var selectedChecklist: [String]? {
get {
guard let savedItem = (UserDefaults.standard.object(forKey: "selectedChecklist")) as? Data else { return nil }
guard let data = NSKeyedUnarchiver.unarchiveObject(with: savedItem) as? [String]? else { return nil}
return data
}
set {
guard let value = newValue else {
UserDefaults.standard.removeObject(forKey: "selectedChecklist")
return
}
let item = NSKeyedArchiver.archivedData(withRootObject: value)
UserDefaults.standard.set(item, forKey: "selectedChecklist")
UserDefaults.standard.synchronize()
}
}
}
usage in your ViewController:-
ClassUserDefaults.shared.selectedChecklist = selectedChecklist
also you want to set wherever you want like:-
cell.textLabel?.text = ClassUserDefaults.shared.selectedChecklist[indexPath.row]
Hope it helps :)

IndexPath for variable row

I am using a UITableView with prototype cells. The main TableView is DiveDetails2VC and the prototype cell is based on DiveItemViewController via segue.
I need to save to parse the results, and have been able to save only row 0 to parse. I do not know how to set this up so that any row selected in the tableview is sent to parse. I am aware this is caused by the line in saveEntry:
let indexPath = NSIndexPath(forRow: 0, inSection: 0)
but I do not know how to set the forRow statement to allow any row within the displayed array. There is only one section.
DiveItemViewController
class DiveItemViewController: UITableViewController, ItemDataProtocol
{
private let NumberOfSections: Int = 1
// MARK: - Public Properties
//
// This property is an object that conforms to the ItemDataSelectedProtocol. We use it to call the
// selectedItem method.
//
var itemDataSelectedDelegate: AnyObject?
private var itemData: Array<String> = Array<String>()
override func viewDidLoad()
{
super.viewDidLoad()
// Adds "+" to dive item selection so divers can add another item to the selected list
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .Add, target: self, action: #selector(DiveItemViewController.AddItemButton(_:)))
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
}
// ---------------------------------------------------------------------------------------------
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell: UITableViewCell! = tableView.dequeueReusableCellWithIdentifier(Resource.DiveItemCell)
if self.itemData.isEmpty == false
{
cell.textLabel?.text = itemData[indexPath.row]
}
parseItem = cell.textLabel!.text!
return cell
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int
{
return self.NumberOfSections
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return itemData.count
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
tableView.cellForRowAtIndexPath(indexPath)?.accessoryType = UITableViewCellAccessoryType.Checkmark
if self.itemDataSelectedDelegate?.respondsToSelector(#selector(DiveDetails2VC.itemDataSelectedItem(_:))) != nil
{
(self.itemDataSelectedDelegate as! ItemDataSelectedProtocol).itemDataSelectedItem(indexPath.row)
}
tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
override func tableView(tableView: UITableView, willDeselectRowAtIndexPath indexPath: NSIndexPath) -> NSIndexPath?
{
tableView.cellForRowAtIndexPath(indexPath)?.accessoryType = UITableViewCellAccessoryType.None
return indexPath
}
func appendData(data: Array<String>) {
}
#IBAction func saveEntry (sender: AnyObject) {
let indexPath = NSIndexPath(forRow: 0, inSection: 0)
let cell = tableView.cellForRowAtIndexPath(indexPath)
let updateDivelog2Query = PFQuery(className: "divelog")
updateDivelog2Query.whereKey("uuid", equalTo: diveUUID)
updateDivelog2Query.getFirstObjectInBackgroundWithBlock {(objects: PFObject?, error: NSError?) -> Void in
if let updateDivelog2Object = objects {
updateDivelog2Object.setValue (self.itemData[indexPath.row], forKey: cell!.textLabel!.text!)
updateDivelog2Object.pinInBackground()
updateDivelog2Object.saveInBackgroundWithBlock {(done:Bool, error:NSError?) in
if done {
print ("ParseData UPDATED data saved")
} else {
updateDivelog2Object.saveEventually()
}
}}}
}
func itemTitle(title: String)
{
self.navigationItem.title = title
}
#IBAction func AddItemButton (sender: AnyObject) {
let alert = UIAlertController(title: "Add item",
message: "Add a new Item to your list",
preferredStyle: .Alert)
let saveAction = UIAlertAction(title: "Save",
style: .Default,
handler: { (action:UIAlertAction) -> Void in
let textField = alert.textFields!.first
self.itemData.append(textField!.text!)
self.tableView.reloadData()
self.appendData(self.itemData)
})
let cancelAction = UIAlertAction(title: "Cancel",
style: .Default) { (action: UIAlertAction) -> Void in
}
alert.addTextFieldWithConfigurationHandler {
(textField: UITextField) -> Void in
}
alert.addAction(saveAction)
alert.addAction(cancelAction)
presentViewController(alert,
animated: true,
completion: nil)
tableView.reloadData()
}
func itemData(data: Array<String>)
{
self.itemData = data
}
}
Declare a var in your viewController:
var selectedIndexPath: NSIndexPath?
And then in your didSelectRowAtIndexPath, set this var with the selected indexPath like:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
if let _ = self.selectedIndexPath {
selectedIndexPath = indexPath
}else{
selectedIndexPath = NSIndexPath(forRow: indexPath.row, inSection: indexPath.section)
}
tableView.cellForRowAtIndexPath(indexPath)?.accessoryType = UITableViewCellAccessoryType.Checkmark
if self.itemDataSelectedDelegate?.respondsToSelector(#selector(DiveDetails2VC.itemDataSelectedItem(_:))) != nil
{
(self.itemDataSelectedDelegate as! ItemDataSelectedProtocol).itemDataSelectedItem(indexPath.row)
}
tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
And then use this selectedIndexPath like this in your saveEntry method:
#IBAction func saveEntry (sender: AnyObject) {
if let indexPath = selectedIndexPath {
let cell = tableView.cellForRowAtIndexPath(indexPath)
...
}
}
EDIT: Added ")" behind "inSection: indexPath.section)"

Resources