Я создаю простое приложение со списком покупок, в котором вы можете ввести свой элемент в поле UIText в ячейке UITableview. см. Изображение
Снимок экрана
После того, как пользователь наберет элемент и нажмет Enter. Я хотел бы сохранить это в основном объекте данных ListItem, а затем создать новую строку в ячейке UITableView, готовую для ввода следующего элемента.
Просто чтобы немного усложнить ситуацию, я планировал используя этот ViewController для отображения списка, который был отправлен другим человеком с уже введенными элементами.
Вот мой код для UIViewController, который содержит представление таблицы. Дайте мне знать, если вам понадобится помощь.
import UIKit
import CoreData
protocol AddItemControllerDelegate {
func controller(_ controller: ListViewController, didAddNewItemWithName: String)
}
class ListViewController: UIViewController, UITextFieldDelegate, UITableViewDelegate, UITableViewDataSource{
private lazy var persistentContainer: NSPersistentContainer = {
let appDelegate = UIApplication.shared.delegate as? AppDelegate
return appDelegate!.persistentContainer
}()
private lazy var fetchedListsController: NSFetchedResultsController<List> = {
let fetchRequest: NSFetchRequest<List> = List.fetchRequest()
fetchRequest.sortDescriptors = [
NSSortDescriptor(key: "ownerID", ascending: false)
]
let controller = NSFetchedResultsController(
fetchRequest: fetchRequest,
managedObjectContext: persistentContainer.viewContext,
sectionNameKeyPath: nil, cacheName: nil)
controller.delegate = self
do {
try controller.performFetch()
} catch {
fatalError("###\(#function): Failed to perform list Fetch: \(error)")
}
return controller
}()
private lazy var fetchedItemsController: NSFetchedResultsController<ListItem> = {
let fetchRequest: NSFetchRequest<ListItem> = ListItem.fetchRequest()
fetchRequest.sortDescriptors = [
NSSortDescriptor(key: "date", ascending: false)
]
let controller = NSFetchedResultsController(
fetchRequest: fetchRequest,
managedObjectContext: persistentContainer.viewContext,
sectionNameKeyPath: nil, cacheName: nil)
controller.delegate = self
let predicate = NSPredicate.init(format: "%K == %@","listID", predicateID! as CVarArg)
do {
fetchRequest.predicate = predicate
try controller.performFetch()
} catch {
fatalError("###\(#function): Failed to perform list item Fetch: \(error)")
}
return controller
}()
private lazy var fetchedPersonController: NSFetchedResultsController<Person> = {
let fetchRequest: NSFetchRequest<Person> = Person.fetchRequest()
fetchRequest.sortDescriptors = [
NSSortDescriptor(key: "listID", ascending: false)
]
let controller = NSFetchedResultsController(
fetchRequest: fetchRequest,
managedObjectContext: persistentContainer.viewContext,
sectionNameKeyPath: nil, cacheName: nil)
controller.delegate = self
do {
try controller.performFetch()
} catch {
fatalError("###\(#function): Failed to perform person Fetch: \(error)")
}
return controller
}()
var date = Date()
let dateFormater = DateFormatter()
var owner: Person?
var predicateID: UUID!
//MARK: Body
@IBOutlet weak var tv: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
print("....")
print(predicateID.uuidString)
print("....")
tv.delegate = self
tv.dataSource = self
let doneButton = UIBarButtonItem(title: NSLocalizedString("Done", comment: ""),
style: .done,
target: self,
action: #selector(unwindToHome(_:)))
navigationItem.rightBarButtonItem = doneButton
}
override func viewWillAppear(_ animated: Bool) {
//Create the list object
createList(pownerID: owner!.ownerID, plistID: predicateID)
// Test if there are any items for the list, if there is no items a new item is created
if fetchedItemsController.fetchedObjects!.count == 0{
createListItem(plistID: predicateID)
}
refreshFetch()
}
// MARK: - Table view data source
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let rows = fetchedItemsController.sections![section].numberOfObjects
if rows == 0 {
return 1
}
return rows
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "listCell", for: indexPath) as! ListTableViewCell
cell.itemText.font?.withSize(20)
if fetchedItemsController.fetchedObjects?.isEmpty == false{
cell.itemText.delegate = self
cell.itemText.becomeFirstResponder()
if cell.checkButton.isSelected == true{
fetchedItemsController.object(at: indexPath).isComplete = true
}else {
fetchedItemsController.object(at: indexPath).isComplete = false
}
fetchedItemsController.object(at: indexPath).item = cell.itemText.text
}
print("*****")
print(fetchedItemsController.object(at: indexPath))
print("*****")
save()
return cell
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete{
let item = fetchedItemsController.object(at: indexPath)
item.managedObjectContext?.delete(item)
}
}
//insert the list data into the Coredata store and create a new line in the tableview
@IBAction func newLine(_ sender: UITextField) {
refreshFetch()
tv.reloadData()
}
@IBAction func unwindToHome(_: Selector){
self.performSegue(withIdentifier: "unwindToHome", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
}
}
extension ListViewController: NSFetchedResultsControllerDelegate{
func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
tv.beginUpdates()
}
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
switch (type) {
case .insert:
if let indexPath = newIndexPath {
tv.insertRows(at: [indexPath], with: .fade)
}
break;
case .delete:
if let indexPath = indexPath {
tv.deleteRows(at: [indexPath], with: .fade)
}
break;
case .move:
print("Object moved")
case .update:
createListItem(plistID: predicateID)
break;
@unknown default:
fatalError()
}
}
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType) {
switch type {
case .insert:
tv.insertSections(IndexSet(integer: sectionIndex), with: .fade)
case .delete:
tv.deleteSections(IndexSet(integer: sectionIndex), with: .fade)
case .move:
break
case .update:
break
@unknown default:
fatalError()
}
}
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
// tv.endUpdates()
}
func save(){
do {
try persistentContainer.viewContext.save()
print("Save sucessful")
} catch {
print("Error occured in save \(error)")
}
}
func refreshFetch(){
do {
try fetchedItemsController.performFetch()
} catch {
print("\(error)")
}
}
func createList(pownerID: UUID, plistID: UUID) {
let list = List(context: persistentContainer.viewContext)
let date = Date()
list.date = date
list.listID = plistID
list.ownerID = pownerID
}
func createListItem(plistID: UUID){
let date = Date()
let item = ListItem.init(context: persistentContainer.viewContext)
item.listID = plistID
item.date = date
item.isComplete = false
// print("##########")
// print(item)
// print("##########")
}
}
PS Я новичок ie Все еще учусь, так что будьте осторожны.