视图控制器之间的变量和传输数据

时间:2014-01-23 03:08:21

标签: ios objective-c nsuserdefaults transfer

我知道到处都有教程,但由于某些原因我无法弄清楚这一点。我有一个标签栏控制器。每个选项卡链接到导航控制器,导航控制器被绑定到视图控制器。所以,2个主视图控制器(StatusVC和TransactionsVC)。

在StatusVC中,我有一个文本字段。在TransVC中,我有一个表格视图。一个人在桌子上添加一个单元格。数学是在幕后完成的。单元格值加在一起(数字)。此信息将发送回StatVC以进行计算和显示数据。我已经把数学部分搞定了。我的问题:如何在视图控制器之间传输数据,更好的是,如何存储这些数据以便在退出时不会被删除(可能是NSUserDefaults)?

我认为,按下选项卡并显示视图时,可以分解数据传输,数据保存和数据显示。

我希望这是有道理的。无论如何,这是我得到的代码。你在看TranVC。用户使用警报视图将数据输入到表中。您正在查看Alert View委托方法的一部分。这是用户将数据输入单元格时(按下完成)。使用*******评论查找关键区域。

StatusViewController *statVC = [[StatusViewController alloc]init]; //*******init

            // Set the amount left in the budget
            NSString *amountToSpend = statVC.amountLeftInBudget.text;
            double budgetLabel = [amountToSpend doubleValue];

            NSString *lastItem = [transactions objectAtIndex:0];
            double lastLabel = [lastItem doubleValue];

            double totalValue = budgetLabel - lastLabel;

            NSString *amountToSpendTotal = [NSString stringWithFormat: @"%.2f", totalValue];

            statVC.amountLeftInBudget.text = amountToSpendTotal; //*******set text (but not save), either way, this doesn't work

            // Set the amount spent
            NSString *sum = [transactions valueForKeyPath:@"@sum.self"];
            double sumLabel = [sum doubleValue];

            NSString *finalSum = [NSString stringWithFormat:@"%.2f", sumLabel];

            //Set the amountSpent label
            statVC.amountSpent.text = finalSum;  //*******set text (but not save), either way, this doesn't work


            // The maxed out budget section
            if ([statVC.amountLeftInBudget.text isEqualToString: @"0.00"]) //*******set color (but not save), either way, this doesn't work

            {
                statVC.amountLeftInBudget.textColor = statVC.currencyLabel.textColor = [UIColor redColor];
            } else if ([statVC.amountLeftInBudget.text compare:@"0.00"] == NSOrderedAscending)
            {
                statVC.amountLeftInBudget.textColor = statVC.currencyLabel.textColor = [UIColor redColor];
            } else if ([statVC.amountLeftInBudget.text compare:@"0.00"] == NSOrderedDescending)
            {
                statVC.amountLeftInBudget.textColor = statVC.currencyLabel.textColor = [UIColor colorWithRed:23.0/255.0 green:143.0/255.0 blue:9.0/255.0 alpha:1.0];
            }

            if ([statVC.amountLeftInBudget.text compare:@"0.00"] == NSOrderedAscending)
            {
                // Create our Installation query
                UIAlertView *exceed;
                exceed = [[UIAlertView alloc]
                          initWithTitle: @"Budget Exceeded"
                          message: @"You have exceeded your budget amount"
                          delegate: self
                          cancelButtonTitle: @"Okay"
                          otherButtonTitles: nil];
                [exceed show];
            }

任何帮助都会令人惊讶。

2 个答案:

答案 0 :(得分:2)

这确实是一个普遍的问题。

有各种解决方案。我建议的是使用数据容器单例。在目标C中对单例设计模式进行谷歌搜索。你甚至可以在SO上找到它的例子。

创建包含要共享的值的属性的单例。然后教你的单身人士保存它的数据。您可以使用用户默认值,您可以使用NSCoding,您可以将数据提取到字典并将其保存到文档目录中的plist文件或其他各种方案中。

答案 1 :(得分:0)

像Duncan建议的那样,Singleton模式可能是最好的选择。如果将共享数据放入模型类中,则可以创建可用于获取单个对象的类方法。

<强> MyModel.m

@implementation MyObject

- (id) init
{
    return nil; // We force the use of a singleton. Probably bad practice?
}

// Private initializer used by the singleton; not included in the header file.
- (id)initAsSingleton {
    self = [super init];
    if (self) {
        // Initialize your singleton instance here. 
    }
    return self;
}

+ (MyModel *)sharedMyModel {
    static MyModel *myModel = nil;

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        myModel = [[MyModel alloc] initAsSingleton];
    });

    return myModel;
}

<强> MyModel.h

@interface MyModel : NSObject

+ (MyModel *)sharedMyModel; // Singleton instance.

@end

这不能防止您使用[[MyModel alloc] init];。它返回一个nil对象,这可能是我最糟糕的编程,但它确实强迫你使用singleton对象。要在每个视图控制器中使用,只需使用以下行来获取单例实例。

MyModel *model = [MyModel sharedMyModel];

将数据存储到其中,然后返回到其他视图控制器并再次获取单例。你将掌握所有数据。

在考虑之后,您还可以强制默认初始化程序只返回您的单例实例,如:

- (id)init {
    return [MyModel sharedMyModel];
}