Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 试图通过prepareForSegue追加数组中的对象时,该对象被替换_Swift - Fatal编程技术网

Swift 试图通过prepareForSegue追加数组中的对象时,该对象被替换

Swift 试图通过prepareForSegue追加数组中的对象时,该对象被替换,swift,Swift,当我运行代码时,一切运行正常,没有错误。但是,当我尝试使用add按钮、segue和文本字段将单元格添加到表视图时,我无法这样做。发生的情况是,当我将对象(自定义)附加到用于创建单元格的数组中时,数组被清空并再次填充。这样做的结果是一次在表视图中只有一个单元格。代码如下 斯威夫特: struct Routine { var name: String? var desc: String? } RoutineListViewController.swift: class Routi

当我运行代码时,一切运行正常,没有错误。但是,当我尝试使用add按钮、segue和文本字段将单元格添加到表视图时,我无法这样做。发生的情况是,当我将对象(自定义)附加到用于创建单元格的数组中时,数组被清空并再次填充。这样做的结果是一次在表视图中只有一个单元格。代码如下

斯威夫特:

struct Routine {

    var name: String?
    var desc: String?
}
RoutineListViewController.swift:

class RoutineListViewController: UIViewController, UITableViewDelegate,              UITableViewDataSource {

    var routines = [Routine]()

    override func viewDidLoad() {
        super.viewDidLoad()

    println("There are \(routines.count) routine(s).")

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    return routines.count
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier("RoutineCell", forIndexPath: indexPath) as UITableViewCell

    var cellName = routines[indexPath.row].name!

    cell.textLabel?.text = cellName

    return cell
}

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    }
}
EditRoutineViewController:

class EditRoutineViewController: UIViewController {

    var newRoutine = Routine(name: "", desc: "")
    var routineName: String?
    var routineDescription: String?

    var allTextFields: UITextField?

@IBOutlet weak var nameField: UITextField!

@IBOutlet weak var descriptionField: UITextField!

override func viewDidLoad() {
    super.viewDidLoad()
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

func textFieldShouldReturn(textField: UITextField) -> Bool {

    allTextFields = textField

    if (textField.placeholder == "Name") {

        if (textField.text != nil) {

        routineName = textField.text
        println("Routine name set as '\(routineName)'")
        }

        textField.resignFirstResponder()

        return true

    } else if (textField.placeholder == "Description") {

        if (textField.text != nil) {

        routineDescription = textField.text
        println("Routine description set as '\(routineDescription!)'")
        }

        textField.resignFirstResponder()

        return true
    }

    return true
}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

        let navController = segue.destinationViewController as UINavigationController
        let RoutineListController = navController.topViewController as RoutineListViewController

        println("There are \(RoutineListController.routines.count) routines in the routines array.")
        RoutineListController.routines.append(newRoutine)
        println("There are \(RoutineListController.routines.count) routines in the routines array.")
        println("A new routine called \(newRoutine.name!) has been added to the routines array.")
}

@IBAction func cancel(sender: AnyObject) {
    allTextFields?.endEditing(true)
    self.dismissViewControllerAnimated(true, completion: nil)
}

@IBAction func done(sender: AnyObject) {

    routineName = self.nameField.text
    routineDescription = self.descriptionField.text

    if (self.nameField.text == "") {

        // Display alert view
        let nameAlert = UIAlertController(title: "Oops!", message:
            "Make sure you enter a name for the routine", preferredStyle: UIAlertControllerStyle.Alert)

        nameAlert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Cancel, handler: nil))

        self.presentViewController(nameAlert, animated: true, completion: nil)

    } else {

        println("A routine called \(self.routineName!) is about to be created.")

        if (self.routineDescription != nil) {
            println("It has a description of '\(self.routineDescription!)'.")
        }

        var localRoutine = Routine(name: routineName, desc: routineDescription?)

        self.newRoutine = localRoutine

        view.endEditing(true)

        self.performSegueWithIdentifier("showRoutines", sender: nil)
        }
    }
}

我大胆猜测,问题在于
EditRoutineViewController
中的代码,它保存新例程并退出/导航回
RoutineViewController
视图。也就是说,通过这段代码:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    let navController = segue.destinationViewController as UINavigationController
    let RoutineListController = navController.topViewController as RoutineListViewController

    RoutineListController.routines.append(newRoutine)
}
创建
RoutineViewController
新实例,并将其推送到导航堆栈上。由于
RoutineViewController
以一个空的
Routine
数组开始,您只需添加一个新创建的项。等等,等等(我无法从代码中看到如何从
RoutineViewController
调用编辑窗口,但它似乎是这样工作的)

如果确实如此,则需要稍微更改应用程序流。因此,我假设应用程序是从
RoutineViewController
视图启动的,只要点击“添加”或“+”按钮,该视图就会显示
EditRoutineViewController
EditRoutineViewController
还应使用两种方法定义协议(我们称之为
EditRoutineDelegate
):

protocol EditRoutineDelegate {
    func didSaveRoutine(routine: Routine)
    func didCancelEnteringRoutine()
}
您需要将例程保存例程(咯咯咯咯)修改为如下内容:

} else {
    var localRoutine = Routine(name: routineName, desc: routineDescription?)
    self.newRoutine = localRoutine
    view.endEditing(true)

    self.delegate.didSaveRoutine(self.newRoutine)
 }
func didSaveRoutine(routine: Routine) {
    routines.append(routine)
    tableView.reloadData()
    navigationController.dismissViewControllerAnimated(true, completion: nil)
}
因此,现在,当您在
EditRoutineViewController
中输入一个新例程时,它将调用其委托,
RoutineViewController
来执行添加新例程和刷新表视图的操作。实现可以是这样的:

} else {
    var localRoutine = Routine(name: routineName, desc: routineDescription?)
    self.newRoutine = localRoutine
    view.endEditing(true)

    self.delegate.didSaveRoutine(self.newRoutine)
 }
func didSaveRoutine(routine: Routine) {
    routines.append(routine)
    tableView.reloadData()
    navigationController.dismissViewControllerAnimated(true, completion: nil)
}
并且,
didcancenteringrouting
可以关闭模式窗口

我很乐意澄清我没有提到的任何细节

PS:我想你已经掌握了授权工作的知识。如果不是的话,花些时间学习这个概念将是一个好主意,因为它是可可中广泛使用的模式


编辑:这是一个具有所需功能的。我希望这样会更清楚。

我对Swift相当陌生,所以我对代表的了解非常模糊。我知道,我得到的错误可能是一个非常简单的修复,但由于我不理解您的解决方案,我希望您的帮助,以了解它。下面是我收到的错误截图:@rodrigochousal我添加了一个指向演示项目的链接,该项目具有您需要的功能。连同我最初的答案,它应该提供足够的背景。