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

问题描述:

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

我有这些类文件:

/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中,我已经成功地插入副视点“登录”,并将其显示在应用程序启动时。

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

下面是我用的代码:

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”子视图设置新的视图控制器。

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

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

任何帮助表示赞赏。因为我是Objective-C和iPhone编程的新手,请尽力解释考虑一位新手程序员:)

再次感谢。

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

+0

谢谢,我会按照这样的方式。 – TamTam 2009-10-15 16:29:11

好的,让我回答我的问题。我刚刚在*上找到了答案。COM

在其将要加载下一个视图控制器视图控制器,只需添加这些行:

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

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

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

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