#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
то, что управляет пользовательским интерфейсом от вашего имени.