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