【问题标题】:Edit operation is not working in Core Data编辑操作在 Core Data 中不起作用
【发布时间】:2021-11-16 01:45:24
【问题描述】:

我正在处理核心数据 crud 操作。我有 Person 对象,当用户单击添加 (+) 按钮时,用户可以添加人名,人名将显示在 tableview 中。当用户单击任何 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()
        
    }
}

【问题讨论】:

    标签: ios swift core-data


    【解决方案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)
    }
    

    【讨论】:

    • 谢谢现在编辑功能工作正常你能看到我的第二个问题意味着以前的用户在我输入新用户之前没有显示为什么它会发生请检查
    • 您管理数据源的逻辑是不必要的昂贵。而不是再次获取数据并在修改数据源数组时调用reloadDate,而是向items 添加一个新项目并调用insertRows,或者在编辑的情况下调用reloadRows。或者考虑使用 NSFetchedResultsController 代表您管理 UI。
    猜你喜欢
    • 2017-02-26
    • 1970-01-01
    • 1970-01-01
    • 2020-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-20
    • 1970-01-01
    相关资源
    最近更新 更多