Swift - 在视图控制器之间传递数据

Posted

技术标签:

【中文标题】Swift - 在视图控制器之间传递数据【英文标题】:Swift - Passing data between view controllers 【发布时间】:2015-05-05 05:48:14 【问题描述】:

我是移动开发的新手,我正在使用 Swift 构建一个 ios 应用程序,该应用程序涉及用户以导航控制器堆栈中的多个视图控制器的形式回答一系列问题的过程。

基本上,我需要从用户在从控制器 A 到控制器 D 的过程中单击的所有按钮中捕获文本。(单击一个按钮会导致下一个视图控制器)到那时,用户到达控制器 D ,我想要一个代表他从控制器 A 到 C 按下的数据的数组。

在控制器 D 上,我询问用户是否愿意重复该过程。例如,我会询问用户他们拥有的汽车,如果他们拥有另一辆汽车,D 会将他们带回控制器 A 并再次重复该过程,其中新的响应将保存为另一个数组。

在用户没有更多汽车后,程序继续进行下一部分,我需要从之前加载这些数组并根据他们输入的内容显示不同的视图控制器。

处理此问题的最佳方法是什么?我曾考虑使用 SQlite 临时保存数据,但其他人告诉我使用 NSUserDefaults,因为它需要的时间更少。我不需要此应用程序的持久性,因为我希望用户在退出应用程序后从头开始重新启动该过程。

【问题讨论】:

即使你不关心持久性,你也可以使用 nsuserdefaults 来保持简单。然后,您可以在应用程序下次启动时忽略存储的值,甚至在应用程序启动时删除它们。需要一些代码示例?迅速?目标-c? 【参考方案1】:

在其中一个视图控制器中存储一个值:

let userDefaults = NSUserDefaults.standardUserDefaults()
// user tapped on button 3 (value 2, because 4 buttons => indices 0-3)
userDefaults.setInteger(2, forKey: "Answer1")
userDefaults.synchronize()

回答所有问题后加载值:

let userDefaults = NSUserDefaults.standardUserDefaults()
let answer1 = userDefaults.integerForKey("Answer1")
let answer2 = userDefaults.integerForKey("Answer2")
...
userDefaults.synchronize()

在应用程序启动时删除保存的内容(在 applicationdidfinishlaunching 中):

let userDefaults = NSUserDefaults.standardUserDefaults()
userDefaults.removeObjectForKey("Answer1")
userDefaults.removeObjectForKey("Answer2")
...
userDefaults.synchronize()

祝你好运! :)

【讨论】:

【参考方案2】:

我认为从控制器 A 到控制器 D 的路径可以称为您的用户的会话。 您需要一种在任何控制器之外存储有关此会话的信息的方法,并且可以从任何控制器访问此会话。

你应该创建一个 Session 类(抱歉,objective-C 中的示例而不是 Swift 中的示例):

会话.h

@interface Session : NSObject

- (void)addValue:(id)value;
- (NSArray *)allValues;
- (NSUInteger)valueCount;
- (void)reset;

@end

会话.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

这样,您可以创建一个全局可访问的 Session 对象 (Session *s = [[Session alloc] init];),并在您的所有控制器中使用它。

【讨论】:

【参考方案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
         

     

 

由于它们是通过引用传递的,因此更改“remoteObject”中的数据成员也会更改“localObject”中的数据成员,因为它们引用的是同一个对象。

【讨论】:

以上是关于Swift - 在视图控制器之间传递数据的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swift 中的视图控制器之间传递数据?

Swift - 在视图控制器之间传递数据

如何在 Swift 中的视图之间传递数据

在 Swift 中的视图控制器之间传递自定义类数据

在 Swift 中的页面视图控制器内的视图控制器之间传递数据

Xcode Swift - 在视图控制器之间传递按钮路径数据