Passing data from the FirstViewController to the LastViewController

烂漫一生 提交于 2019-11-29 17:18:08

Please don't use a singleton, even if the majority of users here tells you so. It would violate the SOLID-Principles for several reasons.

Instead just pass the object from ViewController to ViewController.

If all ViewController expect the same model class, you can create a common base class that has the property for the model.

it could have this method

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.destinationViewControler isKindOfClass:[ProductAwareBaseViewController class]])
    {
        ProductAwareBaseViewController *vc = (ProductAwareBaseViewController *)segue.destinationViewControler;
        vc.product = self.product;
    }
}

I created an example project: https://github.com/vikingosegundo/ProductWizard

Note, that all view controller derive from ProductAwareBaseViewController

@import UIKit;

@class Product;

@interface ProductAwareBaseViewController : UIViewController
@property (nonatomic, strong) Product *product;
@end

#import "ProductAwareBaseViewController.h"
#import "Product.h"

@interface ProductAwareBaseViewController ()

@end

@implementation ProductAwareBaseViewController

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.destinationViewController isKindOfClass:[ProductAwareBaseViewController class]]) {
        ProductAwareBaseViewController *vc = (ProductAwareBaseViewController *)segue.destinationViewController;
        vc.product = self.product;
    }
}
@end

This ViewController knows how to pass the model data of class Product to other instances of ProductAwareBaseViewController and subclasses of it.

All other view controller don't deal with passing the data, just adding each portion of data (name, description, price) to the model and displaying it.

i.e:

#import "EditNameProductViewController.h"
#import "Product.h"

@interface EditNameProductViewController () 
@property (weak, nonatomic) IBOutlet UITextField *nameField;
@end

@implementation EditNameProductViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.product = [[Product alloc] init]; 
}

- (IBAction)continueTapped:(id)sender {
    self.product.productName = self.nameField.text; 
}

@end

#import "EditDescriptionProductViewController.h"
#import "Product.h"

@interface EditDescriptionProductViewController ()
@property (weak, nonatomic) IBOutlet UITextField *descriptionField;
@property (weak, nonatomic) IBOutlet UILabel *nameLabel;
@end

@implementation EditDescriptionProductViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.nameLabel.text = self.product.productName;
}

- (IBAction)continueTapped:(id)sender {
    self.product.productDescription = self.descriptionField.text;
}

@end

Create an object to act as your application's data model. It can be a singleton or it can be a normal object that's available from a known location...such as owned by the app delegate.

Update your model when you have new information and read from the model when you need to display something. Using prepareForSegue: and linking controllers may be acceptable for simple things but it really doesn't scale well.

One way of doing this would be that you create a mutable dictionary (or a custom object with variables) in the first view controller. Then you would pass a weak reference to second/third/fourth view controllers of the mutable dictionary/object from first view controller. Each view controller would be able to set data to the dictionary/object and the last one would be able to process the information.

Another way would be to create a simple singleton class with variables that you want to store. The first view controller would reset the singleton variables. Then let each view controller access the singleton and store their values there, last view controller would process values from singleton.

It depends how many data you are collecting and what you personally prefer.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!