【问题标题】:Object in array is replaced when trying to append it via prepareForSegue尝试通过 prepareForSegue 追加时替换数组中的对象
【发布时间】:2015-03-24 00:47:33
【问题描述】:

当我运行我的代码时,一切都运行良好,没有错误。但是,当我尝试使用添加按钮、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)
        }
    }
}

【问题讨论】:

    标签: swift


    【解决方案1】:

    我大胆猜测问题在于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 视图开始,然后一旦您点击“添加”或“+”按钮,它就会模态显示EditRoutineViewControllerEditRoutineViewController 还应该使用两种方法定义一个协议(我们称之为EditRoutineDelegate):

    protocol EditRoutineDelegate {
        func didSaveRoutine(routine: Routine)
        func didCancelEnteringRoutine()
    }
    

    您需要将保存例程的例程 (chuckle cuggle) 修改为如下内容:

    } 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,它具有您需要的功能。我希望这样会更清楚。

    【讨论】:

    • 我对 Swift 还很陌生,所以我对代表的了解非常模糊。我知道我遇到的错误可能是一个非常简单的修复,但由于我不理解您的解决方案,我希望您能帮助理解它。以下是我收到的错误截图:imgur.com/jfgh3EVimgur.com/NkWPcsR
    • @rodrigochousal 我添加了一个演示项目的链接,该项目具有您需要的功能。除了我原来的答案,它应该提供足够的上下文。
    猜你喜欢
    • 2017-04-03
    • 2021-10-18
    • 1970-01-01
    • 1970-01-01
    • 2011-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多