【问题标题】:Variables and Transferring Data between View Controllers视图控制器之间的变量和数据传输
【发布时间】:2014-01-23 03:08:20
【问题描述】:

我知道到处都有教程,但由于某种原因我无法弄清楚。我有一个标签栏控制器。每个选项卡都链接到一个导航控制器,该控制器连接到一个视图控制器。因此,有 2 个主视图控制器(StatusVC 和 TransactionsVC)。

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

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

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

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];
            }

对此的任何帮助都会令人惊叹。

【问题讨论】:

    标签: ios objective-c nsuserdefaults transfer


    【解决方案1】:

    这确实是一个常见的问题。

    有多种解决方案。我推荐的一个是使用数据容器单例。对 Objective C 中的单例设计模式进行谷歌搜索。你甚至可以在 SO 上找到它的示例。

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

    【讨论】:

    • 谢谢,我会调查的。
    • 好吧,这比我想象的要难。有这方面的好书吗?我需要赶上。
    【解决方案2】:

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

    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 对象,这对我来说可能是糟糕的编程,但它确实迫使您使用单例对象。要在每个视图控制器中使用,您只需使用以下行来获取单例实例。

    MyModel *model = [MyModel sharedMyModel];
    

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

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

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

    【讨论】:

    • 好的,这开始有意义了。谢谢!我会再调查一下。
    • 如果任何答案解决了您的问题,请将其标记为已回答:)
    • 我仍在处理这个问题,一旦我弄清楚了,我会接受答案。我没有接受,因为我可能需要回来寻求帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多