Why Reloaddata Is Showing Error for My Tableview Inside Viewcontroller

Stop tableView.reloadData() throwing an error?

My first guess is that you have not linked the tableview in your storyboard to your view controller.

Maybe you should check this first. Put a break point in viewDidLoad to see if your tableview has been set. If its nil, then there is your problem.

Swift UITableView reloadData() method unexpectedly found nil error

It looks like you are assigning ViewController class to both your first controller (which holds the table view) AND to your second controller (with the text field).

That's not going to work.

Add this class to your project, assign it as the "New Item" view controller's Custom Class, and connect the @IBOutlet and @IBAction:

class NewItemViewController: UIViewController {

// callback closure to tell the VC holding the table view
// that the Add button was tapped, and to
// "send back" the new text
var callback: ((String) -> ())?

@IBOutlet weak var textField: UITextField!

@IBAction func add(_ sender: Any) {
let item: String = textField.text!
callback?(item)
textField.text = ""
}

}

Next, change your ViewController class to the following:

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var editButton: UIBarButtonItem!

var tableViewData = ["Apple", "Banana", "Orange", "Peach", "Pear"]

override func viewDidLoad() {
super.viewDidLoad()

// if you're not already seeing "Apple", "Banana", "Orange", "Peach", "Pear"
// add these two lines
//tableView.dataSource = self
//tableView.delegate = self
}

// MARK: Tableview methods

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tableViewData.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = tableViewData[indexPath.row]
return cell
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// print(tableViewData[indexPath.row])
}

// Allows reordering of cells
func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
return true
}

// Handles reordering of cells
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
let item = tableViewData[sourceIndexPath.row]

tableViewData.remove(at: sourceIndexPath.row)
tableViewData.insert(item, at: destinationIndexPath.row)
}

// Allow the user to delete cells
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == UITableViewCell.EditingStyle.delete {
tableViewData.remove(at: indexPath.row)
tableView.reloadData()
}
}

// MARK: IBActions

@IBAction func edit(_ sender: Any) {
tableView.isEditing = !tableView.isEditing

switch tableView.isEditing {
case true:
editButton.title = "Done"
case false:
editButton.title = "Edit"
}
}

// when "New Item" button is tapped, it will segue to
// NewItemViewController... set the callback closure here

// prepare for segue is called when you have created a segue to another view controller
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

// error checking is always a good idea
// this properly unwraps the destination controller and confirms it's
// an instance of NewItemViewController
if let vc = segue.destination as? NewItemViewController {
// callback is a property we added to NewItemViewController
// we declared it to return a String
vc.callback = { item in
self.tableViewData.append(item)
self.tableView.reloadData()
self.navigationController?.popViewController(animated: true)
}
}
}

}

When you tap the "Add Item" button, we're assuming you have that connected to segue to the "New Item" view controller. By implementing:

override func prepare(for segue: UIStoryboardSegue, sender: Any?)

we will get a reference to the "New Item" view controller that is about to appear, and we'll assign it a "callback closure".

When we type some text and tap the "Add" button in the next controller, it will "call back" to the first controller, passing the newly typed text. That is where we'll update the data array, reload the table, and pop back on the navigation stack.

Swift – Table view data not reloading after dismissing view controller

You are currently prepare entries only on init of PastSessionsDataSource, but not after you did CoreData changes. So each time when you reloadData for tableView you work with the same data set loaded initially. As a quick hack you can try to updated viewDidAppear in a following way:

 override func viewDidAppear(animated: Bool) {
if let tableView = tableView {
let dataSource = tableView.dataSource! as PastSessionsDataSource
dataSource.prepareEntries()
tableView.reloadData()
}
}


Related Topics



Leave a reply



Submit