如何将变量从一个视图控制器传递到另一个?

时间:2009-10-15 14:00:15

标签: iphone objective-c scope

我有三个视图控制器,一个根控制器,一个登录视图控制器和一个客户视图控制器。我想将登录视图控制器中输入的用户名和密码传递给客户视图控制器。我的文件和代码显示如下,请您指导我,如何访问登录视图控制器中设置的变量?或者我如何将变量传递给客户视图控制器?

我有这些类文件:

/classes/MySoftwareAppDelegate.h
/classes/MySoftwareAppDelegate.m
/classes/ViewController.h
/classes/ViewController.m
/classes/LoginController.h
/classes/LoginController.m
/classes/CustomersController.h
/classes/CustomersController.m

我有这些观点:

/resources/MainWindow.xib
/resources/Login.xib
/resources/Customers.xib

在AppDelegate中,我已成功插入子视图“Login”,并在应用程序启动时显示。

在登录视图中,输入我的用户名和密码,然后单击“登录”按钮。单击此按钮时,将触发IBAction。在这个IBAction中,我想用Customers更改当前的子视图。

这是我用过的代码:

MySoftwareAppDelegate.h

#import <UIKit/UIKit.h>

@class ViewController;

@interface MySoftwareAppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow *window;
 ViewController *viewController;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet ViewController *viewController;

@end

MySoftwareAppDelegate.m

#import "MySoftwareAppDelegate.h"
#import "ViewController.h"

@implementation MySoftwareAppDelegate

@synthesize window;
@synthesize viewController;


- (void)applicationDidFinishLaunching:(UIApplication *)application {    

    // Override point for customization after application launch
 [window addSubview:viewController.view];
    [window makeKeyAndVisible];
}


- (void)dealloc {
 [viewController release];
    [window release];
    [super dealloc];
}


@end

ViewController.h

#import <UIKit/UIKit.h>

@class LoginController;

@interface ViewController : UIViewController {
 LoginController *loginController;
}

@property (nonatomic, retain) LoginController *loginController;

@end

ViewController.m

#import "ViewController.h"
#import "LoginController.h"

@implementation ViewController

@synthesize loginController;

- (void)viewDidLoad {
 LoginController *tmpViewController = [[LoginController alloc] initWithNibName:@"Login" bundle:nil];

 self.loginController = tmpViewController;
 [self.view insertSubview:loginController.view atIndex:0];

 [tmpViewController release];

    [super viewDidLoad];
}

- (void)didReceiveMemoryWarning {
 // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

 if (self.loginController.view.superview == nil) {
  self.loginController = nil;
 }

 // Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
 // Release any retained subviews of the main view.
 // e.g. self.myOutlet = nil;
}


- (void)dealloc {
 [loginController release];
    [super dealloc];
}

@end

LoginController.h

#import <UIKit/UIKit.h>

@class CustomersController;

@interface LoginController : UIViewController {
 UIButton *loginButton;
 UITextField *usernameTextField;
 UITextField *passwordTextField;
 NSMutableString *available_credits;
 NSString *current_xml_element;
 CustomersController *customersController;
}

@property (nonatomic, retain) IBOutlet UIButton *loginButton;
@property (nonatomic, retain) IBOutlet UITextField *usernameTextField;
@property (nonatomic, retain) IBOutlet UITextField *passwordTextField;
@property (nonatomic, retain) NSMutableString *available_credits;
@property (nonatomic, retain) NSString *current_xml_element;
@property (nonatomic, retain) CustomersController *customersController;

-(IBAction)textFieldDoneEditing:(id)sender;
-(IBAction)backgroundTap:(id)sender;
-(IBAction)loginToAccount:(id)sender;

@end

LoginController.m

#import "LoginController.h"
#import "CustomersController.h"

@implementation LoginController

@synthesize loginButton;
@synthesize usernameTextField;
@synthesize passwordTextField;
@synthesize customersController;

- (void)viewDidLoad {
 UIImage *buttonImageNormal = [UIImage imageNamed:@"whiteButton.png"];
 UIImage *stretchableButtonImageNormal = [buttonImageNormal stretchableImageWithLeftCapWidth:12 topCapHeight:0];
 UIImage *buttonImagePressed = [UIImage imageNamed:@"blueButton.png"];
 UIImage *stretchableButtonImagePressed = [buttonImagePressed stretchableImageWithLeftCapWidth:12 topCapHeight:0]; 

 [loginButton setBackgroundImage:stretchableButtonImageNormal forState:UIControlStateNormal];
 [loginButton setBackgroundImage:stretchableButtonImagePressed forState:UIControlStateHighlighted];
}

- (void)didReceiveMemoryWarning {
 // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning]; 
 // Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
 // Release any retained subviews of the main view.
 // e.g. self.myOutlet = nil;
}

- (void)dealloc {
 [usernameTextField release];
 [passwordTextField release];
    [super dealloc];
}

-(IBAction)textFieldDoneEditing:(id)sender {
 [sender resignFirstResponder];
}

-(IBAction)backgroundTap:(id)sender {
 [usernameTextField resignFirstResponder];
 [passwordTextField resignFirstResponder];
}

-(IBAction)loginToAccount:(id)sender {

 // bla bla bla... Login check process is done here

 CustomersController *tmpViewController = [[CustomersController alloc] initWithNibName:@"Customers" bundle:nil];
 self.customersController = tmpViewController;

 [self presentModalViewController:tmpViewController animated:YES];
 [self.view removeFromSuperview];

 [tmpViewController release];

}

@end

如上所示,在LoginController.m的loginToAccount方法中,我正在检查登录信息,然后为“customers”子视图设置新的视图控制器。

然后我从超级视图中删除当前的“Login”子视图,但不知道如何添加新的“Customers”子视图。

在MainWindow.xib中,我有一个链接到ViewController类的视图控制器,它是根控制器。

感谢任何帮助。因为我是Objective-C和iPhone编程的新手,所以请尽量解释一下新手程序员的问题:)

再次感谢。

3 个答案:

答案 0 :(得分:3)

好的,让我回答我的问题。我刚刚在StackOverFlow.com上找到答案

在要加载下一个视图控制器的视图控制器中,只需添加以下行:

NextController *tmpViewController = [[NextController alloc] initWithNibName:@"NextView" bundle:nil];
tmpViewController.enteredUsername = usernameTextField.text;
tmpViewController.enteredPassword = passwordTextField.text;     

答案 1 :(得分:2)

我想说更好的方法是使用单独的类来存储全局所需的数据(这将符合MVC模型)。 例如,您可以在MySoftwareAppDelegate中存储登录信息,该信息可以通过应用程序的任何部分[[UIApplication sharedApplication] delegate]调用轻松访问。

答案 2 :(得分:0)

这一切都取决于您想要传递数据的严重程度。对于快速变量(可能是模态视图控制器中的设置更改),TamTam的解决方案最有意义。你分配/初始化它,你得到了变量,为什么不访问它的属性?同样(模态呈现的)视图控制器可以通过委托模式传回变量。

如果您需要系统范围内的数据,则可以使用单例模式。使用“[[UIApplication sharedApplication]委托]”获取应用程序委托(这是一个单例),为方便起见,许多人将其变量填入其中。但是,您的应用代表不是为此而设计的,因此它被认为是糟糕的形式。如果您的苹果不是快速的话,请创建自己的单身人士。

如果您使用sql,plists或coredata等持久数据存储,则可以将系统范围内的数据放在那里。