【问题标题】:How to pass a variable from one view controller to another?如何将变量从一个视图控制器传递到另一个?
【发布时间】:2009-10-15 14:00:15
【问题描述】:

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

我有这些类文件:

/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 编程的新手,考虑到新手程序员,请尽量解释一下:)

再次感谢。

【问题讨论】:

    标签: iphone objective-c scope


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 谢谢,我会照着做的。
      【解决方案3】:

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

      如果您的数据需要在系统范围内,您可以使用单例模式。使用“[[UIApplication sharedApplication] delegate]”获取应用程序委托(这是一个单例),许多人为了方便而将他们的变量放在那里。但是,您的应用程序委托不是为此而设计的,因此它被认为是错误的形式。如果您的苹果不是快手,请创建您自己的单例。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-10-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多