Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.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
Ios swift无法将数据存储回阵列,即使在分段期间也是如此_Ios_Arrays_Swift - Fatal编程技术网

Ios swift无法将数据存储回阵列,即使在分段期间也是如此

Ios swift无法将数据存储回阵列,即使在分段期间也是如此,ios,arrays,swift,Ios,Arrays,Swift,我有两个ViewController,一个是rootviewcontroller,另一个是selectorviewcontroller。在rootvc中,有一个文本字段和按钮,当单击按钮时,它会将我们带到选择器vc,在那里我们可以选择并在必要时添加一个新项目区域,然后选择该项目,在我们选择该项目后,它会将我们带回到rootvc,并在文本字段中显示所选项目。我理解,如果我们不使用数据持久性度量,在重新启动应用程序后,添加的数据将不会持久。虽然我可以将新项目添加到selectorvc,但即使我们将s

我有两个ViewController,一个是rootviewcontroller,另一个是selectorviewcontroller。在rootvc中,有一个文本字段和按钮,当单击按钮时,它会将我们带到选择器vc,在那里我们可以选择并在必要时添加一个新项目区域,然后选择该项目,在我们选择该项目后,它会将我们带回到rootvc,并在文本字段中显示所选项目。我理解,如果我们不使用数据持久性度量,在重新启动应用程序后,添加的数据将不会持久。虽然我可以将新项目添加到selectorvc,但即使我们将segue解回到rootvc并重新输入selectorvc,新添加的数据也会消失。我不确定我哪里做错了,因为数据存储阵列是可变的。如果你能给我指出正确的方向,那就太好了。非常感谢

定义了一个简单数组来存储数据

import UIKit

class AreaClass {
    var areaName: String

    init? (areaName: String) {
        self.areaName = areaName
        if areaName.isEmpty {
            return nil
        }
    }
}
这是rootvc中的放松阶段

@IBAction func unwindWithSelectedArea(segue:UIStoryboardSegue) {
    if let SelectorViewController = segue.sourceViewController as? SelectorViewController,
        selectedArea = SelectorViewController.selectedArea
    {
            AreaSelectedTextField.text = selectedArea
    }
}
这是selectorvc中的声明和addnewitem

var selectedArea: String?
var selectedAreaIndex: Int?
var areas = [AreaClass]()
var newarea = AreaClass?()

override func viewDidLoad() {
    super.viewDidLoad()

    tableView.dataSource = self
    tableView.delegate = self
    areaNewnSelectedTF.delegate = self
    saveButton.enabled = false

    loadSample()
    // Do any additional setup after loading the view.
}


func loadSample (){

    let area1 = AreaClass(areaName: "TopHill")!
    let area2 = AreaClass(areaName: "Foothill")!
    let area3 = AreaClass(areaName: "Summit")!
    let area4 = AreaClass(areaName: "Riverside")!

    areas += [area1, area2, area3, area4]
}


@IBAction func addNewArea(sender: UIBarButtonItem) {
    var dupli = false
    if saveButton == sender {
        let areaname = areaNewnSelectedTF.text ?? ""
        newarea = AreaClass(areaName: areaname)

        for var index = 0; index < areas.count; ++index {
            if areaname == areas[index].areaName {
                dupli = true
                // Mark: alert for duplicate inputs
                let alert = UIAlertController(title: "Duplicate", message: "Can't have same items", preferredStyle:.Alert)
                alert.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
                presentViewController(alert, animated: true, completion: nil)
            }
        }
        if dupli == false {
            let newIndexPath = NSIndexPath(forRow: areas.count, inSection: 0)
            areas.append(newarea!)
            tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Bottom)
        }
    }
}

您需要使用委托将数据从childViewController传递到rootViewController

下面是ViewControllerRot和SelectTableViewControllerselector,它们实现了一个简单的示例,说明了您要查找的内容。我使用了一个struct来简化它

首先,您需要使用delegate=>ViewControllerDelegate的角色和一个带有参数AreaStruct的简单函数创建一个协议。 此协议需要由根用户实现。当您按下按钮时,您将使用将调用prepareForSegue的标识符执行GUE。在其中,您将SelfViewControllerDelegate传递给destinationViewController

在destinationViewController中,用户选择一行。通过选择,它将触发didSelectRowAtIndex。在其中,您将获得所选区域的关注区域结构,并与您的代表一起调用choseArea。。。。之后,弹出ViewController以返回根目录

当您调用choseArea时,它会将areaName放入标签中,以显示您选择的内容,如在RootViewController中实现ChoseareAreastruct:AreaStruct所示。在此函数中,您可以使用AreaStruct执行任何操作

---编辑---

在代码中,selectorviewcontroller创建data=>loadSample。所以,无论当您转到selectorviewcontroller时发生了什么,即使您以前添加了新区域,您也将始终加载Sample。我根据您的示例更新了示例代码

ViewController->按按钮->选择表格ViewController->添加区域->选择区域->返回ViewController

总之,

在ViewController中,我在调用viewDidLoad时设置ListData 我按下按钮转到SelectTableViewController 3我将自己的委托和数据列表传递给PrepareForsgue中的SelectTableViewController SelectTableViewController已加载并基于dataList显示我的列表! 我按下addNewArea,它会将一个新区域附加到SelectTableViewController的本地区域! 我的列表将刷新并显示我的新区域 我选择一个区域 我通过传递两个参数调用代理:我选择的内容和我更新的区域列表;我弹出SelectViewController=>弹出SelectViewController,它会消失,所有数据都会丢失 当我调用代理时,我根据所选内容更新了标签,并使用SelectTableViewController中的区域更新了ViewController中的数据列表。 当我点击我的按钮时,请参见第2.1点你应该明白 如果要持久化数据,可以使用不同的技术,如单例、核心数据、NSUserDefaults等

ViewController.swift

选择TableViewController.swift


您需要使用委托将数据从childViewController传递到rootViewController

下面是ViewControllerRot和SelectTableViewControllerselector,它们实现了一个简单的示例,说明了您要查找的内容。我使用了一个struct来简化它

首先,您需要使用delegate=>ViewControllerDelegate的角色和一个带有参数AreaStruct的简单函数创建一个协议。 此协议需要由根用户实现。当您按下按钮时,您将使用将调用prepareForSegue的标识符执行GUE。在其中,您将SelfViewControllerDelegate传递给destinationViewController

在destinationViewController中,用户选择一行。通过选择,它将触发didSelectRowAtIndex。在其中,您将获得所选区域的关注区域结构,并与您的代表一起调用choseArea。。。。之后,弹出ViewController以返回根目录

当您调用choseArea时,它会将areaName放入标签中,以显示您选择的内容,如在RootViewController中实现ChoseareAreastruct:AreaStruct所示。在此函数中,您可以使用AreaStruct执行任何操作

---编辑---

在代码中,selectorviewcontroller创建data=>loadSample。所以不 无论当您转到selectorviewcontroller时发生了什么,即使您之前添加了新区域,您也将始终加载示例。我根据您的示例更新了示例代码

ViewController->按按钮->选择表格ViewController->添加区域->选择区域->返回ViewController

总之,

在ViewController中,我在调用viewDidLoad时设置ListData 我按下按钮转到SelectTableViewController 3我将自己的委托和数据列表传递给PrepareForsgue中的SelectTableViewController SelectTableViewController已加载并基于dataList显示我的列表! 我按下addNewArea,它会将一个新区域附加到SelectTableViewController的本地区域! 我的列表将刷新并显示我的新区域 我选择一个区域 我通过传递两个参数调用代理:我选择的内容和我更新的区域列表;我弹出SelectViewController=>弹出SelectViewController,它会消失,所有数据都会丢失 当我调用代理时,我根据所选内容更新了标签,并使用SelectTableViewController中的区域更新了ViewController中的数据列表。 当我点击我的按钮时,请参见第2.1点你应该明白 如果要持久化数据,可以使用不同的技术,如单例、核心数据、NSUserDefaults等

ViewController.swift

选择TableViewController.swift


您应该采用使用小写字母命名变量的约定,并且只使用大写字母命名类,这样可以使代码更容易理解。您是否已在prepareForSegue中设置断点并逐步通过它?其中有很多条件展开,这可能意味着代码无法执行。您应该采用使用小写字母命名变量的约定,而只使用大写字母命名类,这会使代码更容易理解。您是否已在prepareForSegue中设置断点并逐步通过它?这里有很多条件展开,这可能意味着代码无法执行。谢谢,我不太明白这一点,但是当按下selectvc中的按钮时,即使没有委托,也不应该将新数据附加到数组中吗?如果您愿意,您可以更改代理,并从array areas:[AreaStruct]传递数组和选定的AreaStruct:func choseAreaareaStruct:AreaStruct。同样使用委托,这是在ViewController之间传输数据的最常见方式。也有NSUserDefaults,但在这种情况下,它不是很有用@DiggerI在这里读了另一个问题,你的意思是,当转换使用堆栈时,segue必须应用某些数据存储技术吗?我更新了我的答案@Digger Copy/Paste/Run my example,如果你不确定它是如何工作的,非常感谢你的详细评论和帮助,@hla,这是一种可行的方法。然而,我仍在试图了解unwind segue是否也可以将数据从childvc传递回rootvc?不过,您是对的,因为loadsample在selectvc中,并且每次都会执行,这就是为什么返回selectvc时数据会重置为sample。谢谢,我不太明白这一点,但是当按下selectvc中的按钮时,即使没有委托,新数据不应该附加到数组中吗?如果您愿意,您可以更改代理,并从array areas:[AreaStruct]传递数组和选定的AreaStruct:func choseAreaareaStruct:AreaStruct。同样使用委托,这是在ViewController之间传输数据的最常见方式。也有NSUserDefaults,但在这种情况下,它不是很有用@DiggerI在这里读了另一个问题,你的意思是,当转换使用堆栈时,segue必须应用某些数据存储技术吗?我更新了我的答案@Digger Copy/Paste/Run my example,如果你不确定它是如何工作的,非常感谢你的详细评论和帮助,@hla,这是一种可行的方法。然而,我仍在试图了解unwind segue是否也可以将数据从childvc传递回rootvc?不过,您是对的,因为loadsample在selectvc中,并且每次都会执行,所以返回selectvc时数据会重置为sample。
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {    
        if segue.identifier == "saveSelectionSegue" {
            if let cell = sender as? UITableViewCell {
                let indexPath = tableView.indexPathForCell(cell)
                if let index = indexPath?.row {
                    selectedArea = areas[index].areaName

                }
            }
        }
    }
import UIKit
import Foundation

struct AreaStruct {
    var areaName : String
}

protocol ViewControllerDelegate : class{
    func choseArea(areaStruct : AreaStruct, areas : [AreaStruct])
}

class ViewController: UIViewController, ViewControllerDelegate { //1. Implement the delegate here.

    @IBOutlet weak var infoLabel: UILabel!
    @IBOutlet weak var btnToVC: UIButton!

    var dataList : [AreaStruct] = [AreaStruct]()

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

    func setupListData(){
        for i in 0...5{
            dataList.append(AreaStruct.init(areaName: "Coucou \(i)"))
        }
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "SelectTableViewController" {
            let destinationViewController = segue.destinationViewController as! SelectTableViewController
            destinationViewController.delegate = self //2. Here you passed itself to the destinationViewController so it can know how to call you !
            destinationViewController.areas = dataList //
        }
    }

    func choseArea(areaStruct : AreaStruct, areas : [AreaStruct]) {
        self.infoLabel.text = areaStruct.areaName
        dataList = areas
    }

    @IBAction func pushToSelectTableViewController(sender: AnyObject) {
        //0. When pressed, you want to go to SelectTableViewController
        self.performSegueWithIdentifier("SelectTableViewController", sender: nil)
    }
}
import UIKit

class SelectTableViewController: UITableViewController {

    var areas : [AreaStruct] = [AreaStruct]()

    weak var delegate : ViewControllerDelegate? // <-- Delegate to send a mess. to ViewController

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

    @IBAction func addNewArea(sender: UIBarButtonItem) {
        let hello_world = "Hello World" //For the example !
        areas.append(AreaStruct.init(areaName: hello_world))
        self.tableView.reloadData()
    }

    // MARK: - Table view data source
    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return areas.count
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath)
        cell.textLabel?.text = areas[indexPath.row].areaName
        return cell
    }

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        let selectedArea = areas[indexPath.row]
        self.delegate?.choseArea(selectedArea, areas: areas) //3. When you select, you pass the data to ViewController via the delegate
        self.navigationController?.popViewControllerAnimated(true)//4. You dismiss itself
    }
}