I have written code for performing Delete,Insert,Update . when I execute my code I'm getting an Error like "Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid index path for use with UITableView. Index paths passed to table view must contain exactly two indices specifying the section and row. Please use the category on NSIndexPath in NSIndexPath UIKitAdditions.h if possible." I'm adding the code here
import UIKit
class ViewController: UIViewController {
@IBOutlet var tableView: UITableView!
@IBOutlet var Insert: UIButton!
@IBOutlet var txtfield: UITextField!
var index = IndexPath()
var models = ["1.Audi","2.Hyundai","3.Bentley","4.Chevrolet","5.Dodge","6.Electric","7.Ford","8.Genesis","9.Honda","10.Ferrari","11.Nissan","12.Porche","13.Range Rover","14.Lamborgini","15.McLaren","16.koneisegg","17.Volvo","18.Mazda","19.Bmw"]
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
@IBAction func textFieldEdit(_ sender: UITextField) {
//self.tableView.reloadData()
if let cell = tableView.cellForRow(at: index) as? UITableViewCell{
cell.textLabel?.text = self.txtfield.text
}
}
@IBAction func insertBtn(_ sender: UIButton) {
if let txt = txtfield.text, !txt.isEmpty{
//self.models.append(txt)
self.models.insert(txt,at: 0)
tableView.beginUpdates()
tableView.insertRows(at: [IndexPath(row: 0, section: 0)], with: .fade)
tableView.endUpdates()
print (models.count)
}
}
}
extension ViewController: UITableViewDataSource,UITableViewDelegate{
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return models.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = models[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
return .delete
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete{
tableView.beginUpdates()
models.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
tableView.endUpdates()
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
index = indexPath
self.txtfield.text = models[indexPath.row]
}
}
CodePudding user response:
You've instantiated an IndexPath
without properties
var index = IndexPath()
If you refer to it before setting a valid property you'll get that error.
Possible Solution
var index: IndexPath?
Use an optional for your index rather than setting an invalid default property. It'll be nil until you assign an instance.
You'll then have to use index?.
or if let index = index
when using the property, but it'll be safe.
CodePudding user response:
You didn't explain when you're getting the error.
Running your code as-is, no apparent errors.
However, my guess is that you're hitting an issue when you haven't yet selected a row, or when you've done something to change the selection while editing in the text field.
Try changing your textFieldEdit
func to this:
@IBAction func textFieldEdit(_ sender: UITextField) {
// make sure
// a row is selected
// and
// we can get a reference to that cell
guard let pth = tableView.indexPathForSelectedRow,
let cell = tableView.cellForRow(at: pth)
else {
return
}
// properly unwrap optional .text property
let str = sender.text ?? ""
// update the data
self.models[pth.row] = str
// update the cell
cell.textLabel?.text = str
}