Reputation: 993
I created a Contact App populated with dummy data and when I try to insert a new contact is not appearing in my UITableView but if I printout my array is showing me that is there. Also my delete is not working very well. Is deleting the whole section instead to delete my selected row. Can you help me to fix my insert function and my delete function ? Thanks.
Here is my code:
class Contact {
var fullName: String
var phoneNumber: String?
init(fullName: String, phoneNumber: String) {
self.fullName = fullName
self.phoneNumber = phoneNumber
}
}
var contactsArray = [Contact]()
var sections = [[Contact]]()
// Logic functionality for my "Contact" application
class ContactViewController: UIViewController, UITextFieldDelegate {
@IBOutlet var nameTextField: UITextField!
@IBOutlet var phoneTextField: UITextField!
@IBOutlet var contactsTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
contactsTableView.delegate = self
contactsTableView.dataSource = self
phoneTextField.delegate = self
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
contactsTableView.reloadData()
}
}
extension ContactViewController: UITableViewDelegate, UITableViewDataSource{
// Add a new contact to the end of list
@IBAction func insertNewContact(_ sender: UIButton) {
if nameTextField.text != nil && nameTextField.text != "" {
contactsArray.append(Contact(fullName: nameTextField.text!, phoneNumber: phoneTextField.text!))
contactsTableView.reloadData()
}
}
// Return no of sections from your list
func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}
// Return no of rows in each section from your list
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sections[section].count
}
// Insert a custom cell in your table view
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let contact = sections[indexPath.section][indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomTableViewCell", for: indexPath) as! CustomTableViewCell
cell.configContact(contact)
return cell
}
// Delete a section when you swipe from right to left
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == UITableViewCellEditingStyle.delete{
sections.remove(at: indexPath.row)
contactsTableView.reloadData() // xCode is confused sometimes and because my outlet var was named "tableView" and not "contactsTableView" it was trying to reload data from the parameter "tableView" of function and delete wasn't working at all. Now is deleting the whole section but I still need to work on it.
}
}
}
Upvotes: 0
Views: 338
Reputation: 154691
Your data is contained in contactsArray
, but your table's data source is sections
array. You need to update the sections
array when contactsArray
is changed.
Move your code that creates the sections
array into its own method. Call it after inserting data into contactsArray
and before calling reloadData()
on the table:
func createSectionsArray() {
let firstLetters = contactsArray.map { $0.titleFirstLetter }
let uniqueFirstLetters = Array(Set(firstLetters))
sortedFirstLetters = uniqueFirstLetters.sorted()
sections = sortedFirstLetters.map { firstLetter in
return contactsArray
.filter { $0.titleFirstLetter == firstLetter }
.sorted { $0.fullName < $1.fullName }
}
}
You'll also want to call it from viewDidLoad()
in place of the code you removed to create the function.
Deleting:
For deleting, first make your Contact
class conform to Equatable
:
class Contact: Equatable {
static func == (lhs: Contact, rhs: Contact) -> Bool {
return lhs.fullName == rhs.fullName && lhs.phoneNumber == rhs.phoneNumber
}
var fullName: String
var phoneNumber: String?
init(fullName: String, phoneNumber: String) {
self.fullName = fullName
self.phoneNumber = phoneNumber
}
}
Then, when an item is deleted, use indexPath.section
and indexPath.row
to look up the contact
, find the contact
in the contactsArray
and remove it, regenerate the sections
array, then reload the table:
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
let contact = sections[indexPath.section][indexPath.row]
if let index = contactsArray.index(of: contact) {
contactsArray.remove(at: index)
createSectionsArray()
contactsTableView.reloadData()
}
}
}
Upvotes: 1