如何保存从一个ViewController到另一个ViewController的数据?

时间:2019-02-21 22:35:52

标签: ios swift core-data save userdefaults

我正在尝试构建待办事项/提醒应用程序。我已经采取了一些措施,但是我陷入了这一“节省”步骤。我有两个viewControllers。一个用于我在哪里注册我的任务,另一个用于在哪里存储这些任务。这可以正常工作,但是一旦我重新启动该应用程序,它就会消失。我已经看过许多关于如何解决此问题的教程和说明,但是对于我这种情况,我需要在一个VC的点击按钮上调用“保存方法”,然后将其存储/加载到表格视图中,但这些教程和说明都没有。另一个VC。

是否有人在其中提供一些技巧或链接,以使我可以阅读此书,或者对如何解决此问题有任何想法?

这是视图的外观(非常简单)。

您注册的视图,字段中的数据正在保存:

The View where you registered, the data in the fields are being saved

第二个Vc与TableView一起存储数据:

The second Vc with the TableView which store the data

以下是第一个Vc的一些代码(您在其中添加/注册新任务的代码):

//
//  ViewControllerNew.swift
//  easy reminder 2
//
//  Created by Andreas Sjöstedt on 2019-02-04.
//  Copyright © 2019 Andreas Sjöstedt. All rights reserved.
//

import UIKit

class ViewControllerNew: UIViewController, UITextFieldDelegate {
    @IBOutlet weak var TaskTextField: UITextField!
    @IBOutlet weak var todaysdate: UILabel!
    @IBOutlet weak var currenttime: UILabel!

    @IBAction func timeSlider(_ sender: UISlider) {
        currenttime.text = String(Int(sender.value))
    }

    @IBAction func SavedButtonPressed(_ sender: Any) {
        ToDoController.addTodo(newTodo: TaskTextField.text! + " " + currenttime.text! + " " + todaysdate.text!)
        // code for add the data in TableView on Edit Site
    }

    var LableTTF = String()

    override func viewDidLoad() {
        super.viewDidLoad()

        getCurrentDate()
        // the current date text//

        getSingle()
        // acces the calendar//

        getCurrentTime()
        // the current time lable//

        TaskTextField.delegate = self
        // the task-text-lable//

        NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: "MyNoteName"), object: nil, queue: OperationQueue.main) { (Notification) in
            let dateVc = Notification.object as! ViewControllerDate
            self.todaysdate.text = dateVc.formattedDate
            // notification reciever
        }
    }

    func getCurrentDate(){
        let formatter = DateFormatter()
        formatter.dateStyle = .short
        //formatter.timeStyle = .medium
        formatter.dateFormat = "dd-MM-yyyy"
        let str = formatter.string(from: Date())
        todaysdate.text = str
        // code for showing current date //
    }

    func getCurrentTime(){
        let formatter = DateFormatter()
        formatter.dateStyle = .short
        formatter.dateFormat = "HH:mm"
        let str = formatter.string(from: Date())
        currenttime.text = str
        // code for showing current time //
    }

    func getSingle(){
        let date = Date()
        let calendar = Calendar.current
        _ = calendar.component(.year, from: date)
        _ = calendar.component(.month, from: date)
        _ = calendar.component(.day, from: date)
        // code for access the calendar //// code for passing the data to other view //
    }

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        TaskTextField.resignFirstResponder()
        return true
        //Hide keyboard when press "klar"//
    }
}

这是另一个Vc的一些代码(其中包含要存储数据的TableView:

//
//  ViewControllerEdit.swift
//  easy reminder 2
//
//  Created by Andreas Sjöstedt on 2019-02-04.
//  Copyright © 2019 Andreas Sjöstedt. All rights reserved.
//

import UIKit

class ViewControllerEdit: UIViewController, UITableViewDelegate, UITableViewDataSource {
    @IBOutlet weak var tableView: UITableView!

    override func viewDidAppear(_ animated: Bool){
        super.viewDidAppear( animated )
        tableView.reloadData()
    }

    func numberOfSections(in tableView: UITableView) -> Int{
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
        return ToDoController.todosArray.count
    }


    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        cell.textLabel?.text = ToDoController.todosArray[indexPath.row]
        cell.textLabel?.textColor = .white
        return cell
    }

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == UITableViewCell.EditingStyle.delete {
            ToDoController.removeTodo(atIndex:  indexPath.row)
            tableView.deleteRows(at: [indexPath], with: .fade)
        }
    }
}

很抱歉,如果要在其中添加此功能,这里还有ToDo控制器的一些代码:


    //
//  ToDoController.swift
//  easy reminder 2
//
//  Created by Andreas Sjöstedt on 2019-02-12.
//  Copyright © 2019 Andreas Sjöstedt. All rights reserved.
//

import UIKit

class ToDoController: NSObject {

    static var todosArray:Array<String> = []

    class func addTodo( newTodo:String){
        ToDoController.todosArray.append(  newTodo)
    }

    class func removeTodo(atIndex:Int) {
        ToDoController.todosArray.remove(at: atIndex)
    }
}

3 个答案:

答案 0 :(得分:0)

您正在将数据保存在ToDoController中,但是您在此处未提及其代码。问题一定出在其中。您可能没有在ToDoController中保存数据。您的ToDoController会保留数据,直到应用程序保持活动状态。当您终止应用程序时,控制器会取消分配数据,但会取消分配数据。如果需要持久性数据,则必须使用Plist,Userdefaults或Coredata。有关永久性数据,请参见link

答案 1 :(得分:0)

您需要为此问题实现协议委托,请使用此代码获取此问题的解决方案,希望对您有所帮助。

import UIKit

protocol ViewControllerNewDelegate {
    func callBackFromViewControllerNew(_ myData:[String:Any])
}

class ViewControllerNew: UIViewController, UITextFieldDelegate {

    weak var delegate: ViewControllerNewDelegate?


    @IBAction func SavedButtonPressed(_ sender: Any) {
        // code for add the data in TableView on Edit Site
        delegate.callBackFromViewControllerNew(//Pass dictionary here)
    }

}

注意:-定义ViewControllerNewDelegate,编写callBackFromViewControllerNew函数,并且在转到ViewControllerNew时不要忘记编写 delegte = self

class ViewControllerEdit: UIViewController, UITableViewDelegate, UITableViewDataSource, ViewControllerNewDelegate {

    func goToViewControllerNew (){
        let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
        let vc = storyBoard.instantiateViewController(withIdentifier: "ViewControllerNew") as! ViewControllerNew
        vc.delegate = self
        self.navigationController?.pushViewController(vc, animated: true)
    }    

    func callBackFromViewControllerNew(_ myData:[String:Any]){
        print(myData) // get data here from ViewControllerNew
    }        
}

答案 2 :(得分:0)

问题出在存储方法的持久性上。

static var todosArray:Array<String> = []

每次重新启动时都会重新创建一次,同时丢失所有值。它不能超过您的应用程序。您需要将待办事项写入文件或数据库中。

有几个选项:核心数据,sqlite数据库,UserDefaults。最后一个是这里最不适合的解决方案,但是它也是最容易实现的,我想这就是您现在想要的。

extension UserDefaults {

    private static let todoKey = "ToDoKey" // name under which todo data are stored

    func addTodo(_ todo: String, date: Date) {
        var todos = allTodos() // mutable reference to be able to change its content
        todos.append((todo, date))

        set(todos, forKey: UserDefaults.todoKey)
    }

    func removeTodo(at index: Int) {
        guard index < numberOfTodos() else { return }

        var todos = allTodos()
        todos.remove(at: index)

        set(todos, forKey: UserDefaults.todoKey)
    }

    func todoValue(at index: Int) -> String? {
        guard index < numberOfTodos() else { return nil }

        return allTodos()[index].0 // retrieve the first value of a tuple
    }

    func todoDate(at index: Int) -> Date? {
        guard index < numberOfTodos() else { return nil }

        return allTodos()[index].1 // retrieve the second value of a tuple
    }

    func numberOfTodos() -> Int {
        return allTodos().count
    }

    private func allTodos() -> [(String, Date)] {
        let todos = object(forKey: UserDefaults.todoKey) as? [(String, Date)]
        return todos ?? [(String, Date)]()
    }

}

您可以按以下方式替换静态数组:

class ToDoController: NSObject {

    class func addTodo( newTodo:String) {
        UserDefaults.standard.addTodo(newTodo, Date())
    }

    class func removeTodo(atIndex:Int) {
        UserDefaults.standard.removeTodo(at: atIndex)
    }
}

要求特定的待办事项:

UserDefaults.standard.todoValue(at: index)
UserDefaults.standard.todoDate(at: index)