尝试通过prepareForSegue附加数组时,将替换数组中的对象

时间:2015-03-21 21:16:18

标签: swift

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

Routine.swift:

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)
        }
    }
}

1 个答案:

答案 0 :(得分:0)

我冒昧地猜测问题出在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模式显示。{1}}或' +'按钮。 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)
 }

因此,现在,当您在EditRoutineViewController中输入新例程时,它会调用其委托RoutineViewController来执行新例程的添加并刷新表视图。实现可能是这样的:

func didSaveRoutine(routine: Routine) {
    routines.append(routine)
    tableView.reloadData()
    navigationController.dismissViewControllerAnimated(true, completion: nil)
}

didCancelEnteringRoutine只能解除模态窗口。

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

PS:我认为你对委托如何运作有工作知识。如果没有,花一些时间学习这个概念是个好主意,因为它是Cocoa中广泛使用的模式。

编辑:这里有一个small demo project,它具有您需要的功能。我希望这样更清楚。