Операция редактирования не работает в основных данных

#ios #swift #core-data

Вопрос:

Я работаю над основной операцией обработки данных.У меня есть объект «Человек», и когда пользователь нажимает кнопку «Добавить» ( ), пользователь может добавить имя человека, и имя человека будет отображаться в виде таблицы. Когда пользователь нажимает на любую ячейку TableView, в ней отображается оповещение и текущее лицо, отображаемое в текстовом поле оповещения, и пользователь может редактировать имя человека, но моя логика не работает нормально, и пользователь не редактирует.У меня есть еще одна проблема, например, когда я запускаю приложение, запись постоянных пользователей не отображается, но она будет отображаться после того, как я введу нового пользователя и приведу всех постоянных пользователей, которые увидят код и направят меня заранее, спасибо.

Класс ViewController:

 @IBOutlet weak var tableView: UITableView!
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

var items : [Person] = [] {
    didSet{
        DispatchQueue.main.async {
            self.tableView.reloadData()
        }
    }
}
override func viewDidLoad() {
    super.viewDidLoad()
    self.tableView.delegate = self
    self.tableView.dataSource = self
    tableView.register(UINib(nibName: String(describing: StundentCell.self), bundle: .main), forCellReuseIdentifier: String(describing: StundentCell.self))
   
}
@IBAction func addPerson(_ sender: UIBarButtonItem) {
    showAlert()
}

private  func showAlert(_ title:String = "Add new Item", message: String = "what is your name"){
    let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
    alertController.addTextField()
    let subbmitBtn = UIAlertAction(title: "Add Person", style: .default) { (action) in
        let textField = alertController.textFields![0]
        let newPerson = Person(context:self.context)
        newPerson.name = textField.text
        newPerson.age = 20
        newPerson.gender = "Male"
        do {
            try self.context.save()
        }
        catch{
            
        }
        self.fetchPerople()
        }
    alertController.addAction(subbmitBtn)
    self.present(alertController, animated: true, completion: nil)
    
}

func fetchPerople(){
    do{
        self.items = try context.fetch(Person.fetchRequest())
    }
    catch{
        
    }
}
}

extension ViewController: UITableViewDelegate,UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return items.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    self.configurePersonCell(tableView, cellForRowAt: indexPath)
}


func configurePersonCell(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
    guard let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: StundentCell.self)) as? StundentCell else {return UITableViewCell()}
    cell.studentData = items[indexPath.row]
    cell.delete.tag = indexPath.row
    cell.delete.addTarget(self, action: #selector(deleteRecord(sender:)), for: .touchUpInside)
    return cell
 }

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    var person =  items[indexPath.row].name
    let alertController = UIAlertController(title: "Edit Person", message: "Edit name", preferredStyle: .alert)
    alertController.addTextField()
    let alertField = alertController.textFields![0]
    alertField.text = person
    
    let saveBtn = UIAlertAction(title: "Save", style: .default) { (action) in
        let getName = alertController.textFields![0]
        person = getName.text
        
        do{
            try self.context.save()
        }
        catch{
            
        }
        self.fetchPerople()
    }
    alertController.addAction(saveBtn)
    self.present(alertController, animated: true, completion: nil)
}

func gotoPersonDetails(personData:Person){
   
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 50
}
@objc func deleteRecord(sender: UIButton){
    if items.count > 0{
        let personRemove = self.items[sender.tag]
        self.context.delete(personRemove)
        
        do {
            try self.context.save()
        }
        catch{
            
        }
        self.fetchPerople()
        
    }
}


@IBOutlet weak var tableView: UITableView!
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

var items : [Person] = [] {
    didSet{
        DispatchQueue.main.async {
            self.tableView.reloadData()
        }
    }
}
override func viewDidLoad() {
    super.viewDidLoad()
    self.tableView.delegate = self
    self.tableView.dataSource = self
    tableView.register(UINib(nibName: String(describing: StundentCell.self), bundle: .main), forCellReuseIdentifier: String(describing: StundentCell.self))
   
}
@IBAction func addPerson(_ sender: UIBarButtonItem) {
    showAlert()
}

private  func showAlert(_ title:String = "Add new Item", message: String = "what is your name"){
    let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
    alertController.addTextField()
    let subbmitBtn = UIAlertAction(title: "Add Person", style: .default) { (action) in
        let textField = alertController.textFields![0]
        let newPerson = Person(context:self.context)
        newPerson.name = textField.text
        newPerson.age = 20
        newPerson.gender = "Male"
        do {
            try self.context.save()
        }
        catch{
            
        }
        self.fetchPerople()
        }
    alertController.addAction(subbmitBtn)
    self.present(alertController, animated: true, completion: nil)
    
}

func fetchPerople(){
    do{
        self.items = try context.fetch(Person.fetchRequest())
    }
    catch{
        
    }
   
}


}


extension ViewController: UITableViewDelegate,UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return items.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    self.configurePersonCell(tableView, cellForRowAt: indexPath)
}


func configurePersonCell(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
    guard let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: StundentCell.self)) as? StundentCell else {return UITableViewCell()}
    cell.studentData = items[indexPath.row]
    cell.delete.tag = indexPath.row
    cell.delete.addTarget(self, action: #selector(deleteRecord(sender:)), for: .touchUpInside)
    return cell
 }

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    
    var person =  items[indexPath.row].name
   

    let alertController = UIAlertController(title: "Edit Person", message: "Edit name", preferredStyle: .alert)
    alertController.addTextField()
    let alertField = alertController.textFields![0]
    alertField.text = person
    
    let saveBtn = UIAlertAction(title: "Save", style: .default) { (action) in
        //get the person name in alert text field
        let getName = alertController.textFields![0]
        //edit the name of the person object
        person = getName.text
        
        do{
            try self.context.save()
        }
        catch{
            
        }
        self.fetchPerople()
    }
    alertController.addAction(saveBtn)
    self.present(alertController, animated: true, completion: nil)
}

func gotoPersonDetails(personData:Person){
   
}


func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 50
}
@objc func deleteRecord(sender: UIButton){
    
    /* fro api calling or firebase for deleting the rows in tableview
    if items.count > 0 {
        items.remove(at:sender.tag)
    }
*/
    
    if items.count > 0{
        let personRemove = self.items[sender.tag]
        //remove the person
        self.context.delete(personRemove)
        
        //save the data
        do {
            try self.context.save()
        }
        catch{
            
        }
        //refetch the data
        self.fetchPerople()
        
    }
}
 

Ответ №1:

Вы изменяете строку имени, но не обновляете запись.

Получите всего человека

 let person = items[indexPath.row] // can be a constant because it's reference type
 

назначьте имя текстовому полю

 alertField.text = person.name
 

и верните отредактированное имя

 let nameField = alertController.textFields![0]
person.name = nameField.text
 

 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let person = items[indexPath.row]
    let alertController = UIAlertController(title: "Edit Person", message: "Edit name", preferredStyle: .alert)
    alertController.addTextField()
    let alertField = alertController.textFields![0]
    alertField.text = person.name
    
    let saveBtn = UIAlertAction(title: "Save", style: .default) { (action) in
        let nameField = alertController.textFields![0]
        person.name = nameField.text
        
        do{
            try self.context.save()
        }
        catch{
            
        }
        self.fetchPerople()
    }
    alertController.addAction(saveBtn)
    self.present(alertController, animated: true, completion: nil)
}
 

Комментарии:

1. Спасибо, теперь функциональность редактирования работает нормально, теперь вы видите, что моя вторая проблема означает, что всепроникающие пользователи не отображаются, пока я не введу новых пользователей, почему это происходит, пожалуйста, проверьте

2. Ваша логика управления источником данных является излишне дорогостоящей. Вместо того, чтобы снова извлекать данные и вызывать reloadDate всякий раз, когда массив источников данных изменяется, добавьте новый элемент items и вызовите insertRows или в случае вызова редактирования reloadRows . Или подумайте о том, чтобы использовать NSFetchedResultsController то, что управляет пользовательским интерфейсом от вашего имени.