如何在一个视图控制器中将数据保存到CoreData中,然后在另一个视图控制器中使用tableview显示数据?

时间:2019-06-06 03:22:50

标签: ios swift core-data tableview

首先,我是快速编程的新手,对很多事情我也不是很清楚,因此我遵循指南来确保我的应用程序可以正常工作。

基本上,我一直遵循(https://www.brianadvent.com/build-simple-core-data-driven-ios-app/)上的指南来构建简单的核心数据驱动的iOS应用。我完全遵循了代码,并且可以正常工作。但是,我不得不对该应用程序进行更多改进,这就是问题所在。

基本上,在指南中,将项目加载到核心数据和tableview中都存在于同一视图控制器中。在我的新应用中,我希望用户输入以相同方式存储在核心数据中的字符串,并让Tableview在另一个View Controller上显示输入的数据。很快,我意识到您不能从不同的视图控制器调用变量和函数,因此我认为在第二个视图控制器中创建新变量和moc应该不是什么大问题。

这是我到目前为止尝试过的。我将所有内容都保留在代码中,因为我担心那可能是错误所在。

第一个视图控制器(数据存储在核心数据中:

from unittest.mock import patch
from a import A,foo
def my_wrapper(*args, **kwargs):
    return A('b')
def bar():
    with patch('a.A', my_wrapper):
        foo()

第二个viewController(表视图所在的位置):

import UIKit
import CoreData

class ViewController: UIViewController {
    //name of entity = Alarm
    var alarmItems = [Alarm]() // array of alarm items called     alarmItems
    var moc: NSManagedObjectContext!
    let appDelegate = UIApplication.shared.delegate as? AppDelegate


    @IBOutlet weak var engineerName: UITextField!

    @IBOutlet weak var dateTimeOfAlarm: UITextField!

    @IBOutlet weak var trueFalseAlarmSelector: UISwitch!

    @IBOutlet weak var engineerComments: UITextField!

    //saving alarm attributes into coredata
    @IBOutlet weak var submitButton: UIStackView!

    override func viewDidLoad() {
        super.viewDidLoad()
        engineerName.delegate = (self as UITextFieldDelegate)
        dateTimeOfAlarm.delegate = (self as UITextFieldDelegate)
        //trueFalseAlarmSelector.delegate = self
        moc = appDelegate?.persistentContainer.viewContext
        // Do any additional setup after loading the view.
        loadData()
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?){
        engineerName.resignFirstResponder()
        dateTimeOfAlarm.resignFirstResponder()
    }

    @IBAction func dateTimeOfAlarmEdit(_ sender: UITextField) {
        let datePickerView = UIDatePicker()
        datePickerView.datePickerMode = .dateAndTime
        sender.inputView = datePickerView
        datePickerView.addTarget(self, action:     #selector(handleDatePicker(sender:)), for: .valueChanged)
    }

    @objc func handleDatePicker(sender: UIDatePicker) {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "dd MMM yyyy HH:mm"
        dateTimeOfAlarm.text = dateFormatter.string(from: sender.date)
    }

    //sending the attributes to the coredata
    @IBAction func submitAlarmAttributes(_ sender: UIButton) {
        let alarmItem = Alarm(context: moc)

        //true/false button checker
        if trueFalseAlarmSelector.isOn {
            alarmItem.trueOrFalseAlarm = true
        } else {
            alarmItem.trueOrFalseAlarm = false
        }

        alarmItem.nameOfEngineer = engineerName.text
        alarmItem.dateTimeOfAlarm = dateTimeOfAlarm.text
        alarmItem.engineerComments = engineerComments.text

        appDelegate?.saveContext()
        loadData()
    }

    //loadData will update the alarmItems array with the new and most current data from the database.
    func loadData(){
        let alarmRequest:NSFetchRequest<Alarm> = Alarm.fetchRequest()
        let sortDescriptor = NSSortDescriptor(key: "dateTimeOfAlarm", ascending: false)
        alarmRequest.sortDescriptors = [sortDescriptor]

        do{try alarmItems=moc.fetch(alarmRequest)

        } catch {
            print("Could not load data")
        }

        //self.tableView.reloadData()

    }
}

extension ViewController : UITextFieldDelegate {
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        return true
    }
}

第一个视图控制器没有任何错误消息。

但是,第二个视图控制器有很多问题。例如,在一开始,就出现此错误类型'SecondViewController'不符合协议'UITableViewDataSource'“。在某些行中有一些错误消息,显示为“源文件中的编辑器占位符”。还有一个“即使我确实有tableView,“ SecondViewController”类型的值也没有成员“ tableView””错误,最后,最后还有“使用未解析的标识符'cell'”。

非常感谢您的帮助,过去几天我一直在努力解决这个问题,我真的不知道还能做什么。

1 个答案:

答案 0 :(得分:0)

我怀疑您所做的是在InterfaceBuilder中复制/粘贴以创建SecondViewController。

您使用的原始代码有一个名为tableView的变量,该变量仍在InterfaceBuilder中引用。要解决此问题,请打开InterfaceBuilder并找到您的SecondViewController。如果尚未展开,请展开场景对象并选择SecondViewController,然后使用右侧的检查器显示“连接检查器”。您可能会发现带有感叹号的tableView插座和另一个名为historyTable的插座。只需删除tableView参考,并确保您的historyTable已正确链接。

关于“未解析的标识符单元格”,这是因为您未正确放置viewDidLoad函数的右括号。由于未关闭函数,因此此后所有其他函数都将创建为viewDidLoad的局部函数,而不是SecondViewController的函数。要修复您的源代码,只需移除return cell上方的括号,然后将其添加到self.historyTable.dataSource = self(是的,当前您将其命名为self.tableView.dataSource,但变量名为historyTable)。