[英]Swift - Passing data between view controllers
I am new to mobile development, and I am building an iOS application with Swift that involves a process where a user answers a series of questions in the form of multiple view controllers in a navigation controller stack. 我是移动开发的新手,我正在用Swift构建一个iOS应用程序,其中涉及一个过程,在该过程中,用户以导航控制器堆栈中的多个视图控制器的形式回答一系列问题。
Basically, I need to capture the text from all the buttons that the user clicks on in his process from controller A to controller D. (One button click leads to the next view controller) By the time, the user reaches controller D, I want to have a array of data that represents what he pressed from controllers A to C. 基本上,我需要捕获用户在其从控制器A到控制器D的过程中单击的所有按钮中的文本。(单击一次按钮会转到下一个视图控制器)到用户到达控制器D时,我要具有代表他从控制器A到C按下的数据的数组。
On controller D, I ask the user if they would like to repeat the process. 在控制器D上,我询问用户是否要重复该过程。 For example, I would ask the user about a car they own, and, if they own another car, D would take them back to controller A and repeat the process again where the new responses would be saved as another array. 例如,我会问用户关于他们拥有的汽车的信息,如果他们拥有另一辆汽车,D会将其带回控制器A,然后再次重复该过程,将新的响应保存为另一个数组。
After the user has no more cars, the program moves on to the next section where I would need to load these arrays from before and display different view controllers based on what they entered. 在用户没有更多的汽车之后,该程序将移至下一部分,在该部分中,我需要从之前加载这些数组,并根据输入的内容显示不同的视图控制器。
What would be the best way to handle this? 处理此问题的最佳方法是什么? I have considered using SQlite to temporarily save the data, but other people have told me to use NSUserDefaults since it takes less time. 我考虑过使用SQlite临时保存数据,但是其他人却告诉我使用NSUserDefaults,因为它花费的时间更少。 I will NOT need persistence for this application since I want the user to restart the process from the beginning after they quit the application. 我不需要该应用程序的持久性,因为我希望用户在退出应用程序后从头开始重新启动该过程。
to store a value in one of the viewcontrollers: 将值存储在其中一个视图控制器中:
let userDefaults = NSUserDefaults.standardUserDefaults()
// user tapped on button 3 (value 2, because 4 buttons => indices 0-3)
userDefaults.setInteger(2, forKey: "Answer1")
userDefaults.synchronize()
to load the values after answering all the questions: 在回答所有问题后加载值:
let userDefaults = NSUserDefaults.standardUserDefaults()
let answer1 = userDefaults.integerForKey("Answer1")
let answer2 = userDefaults.integerForKey("Answer2")
...
userDefaults.synchronize()
to delete the saved stuff on application launch (in applicationdidfinishlaunching): 删除应用程序启动时保存的内容(在applicationdidfinishlaunching中):
let userDefaults = NSUserDefaults.standardUserDefaults()
userDefaults.removeObjectForKey("Answer1")
userDefaults.removeObjectForKey("Answer2")
...
userDefaults.synchronize()
good luck! 祝好运! :) :)
I think the path from controller A to controller D can be called a Session for your user. 我认为从控制器A到控制器D的路径可以称为用户的会话。 What you need is a way to store information about this session outside any controller, and this session to be accessible from any controller. 您需要的是一种在任何控制器外部存储有关此会话的信息的方法,并且可以从任何控制器访问该会话。
You should create a class Session (sorry, example in objective-C not in Swift): 您应该创建一个Session类(抱歉,Objective-C中的示例而不是Swift中的示例):
Session.h 会话h
@interface Session : NSObject
- (void)addValue:(id)value;
- (NSArray *)allValues;
- (NSUInteger)valueCount;
- (void)reset;
@end
Session.m 会话
@interface Session ()
{
NSMutableArray *_values;
}
@end
@implementation Session
- (instancetype)init
{
self = [super init];
if( !self ) return nil;
_values = [[NSMutableArray alloc] init];
return self;
}
- (void)addValue:(id)value
{
[_values addObject:value];
}
- (NSUInteger)valueCount
{
return _values.count;
}
- (NSArray *)allValues
{
// NSArray to have a immutable array of values
return [NSArray arrayWithArray:_values];
}
- (void)reset
{
[_values removeAllObjects];
}
@end
This way, you can create a globally accessible Session object ( Session *s = [[Session alloc] init];
), and use it throughout all your controllers. 这样,您可以创建一个可全局访问的Session对象( Session *s = [[Session alloc] init];
),并在所有控制器中使用它。
Edit : Learned a lot since my original answer. 编辑 :自从我的原始答案中学到了很多。
What I do (this may not be the only way, but works for me), is to instantiate a class of the kind I need on the main View Controller, as well as on each View Controller that modifies the data. 我要做的(这可能不是唯一的方法,但是对我有用)是在主View Controller以及修改数据的每个View Controller上实例化一个我需要的类型的类。 If I need to update information that refers to that class, I pass the object in the segue (Swift 3): 如果我需要更新引用该类的信息,可以在segue中传递对象(Swift 3):
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let identifier = segue.identifier {
switch identifier {
case constants.aSegue: // not the real name of my segue :-P
// grab inside the navcon
if let navCon = segue.destination as? UINavigationController {
if let destinationVC = navCon.viewControllers.first as? CGSettingsPopupViewController {
destinationVC.remoteObject = localObject
// localObject is a kind of the class I need, as is remoteObject
// now, changes to destinationVC.remoteObject will be accessible locally, when the destinationVC returns control
}
}
default:
break
}
}
}
Since they are passed by reference, changing data members in 'remoteObject' also changes the ones in 'localObject' since they refer to the same object. 由于它们是通过引用传递的,因此更改“ remoteObject”中的数据成员也会更改“ localObject”中的数据成员,因为它们引用的是同一对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.