Home > Software engineering >  How to Perform CRUD operation in TableView Swift
How to Perform CRUD operation in TableView Swift

Time:11-18

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]
    
}
}

ScreenShot of My storyBoard

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
}
  • Related