how to pass a string value from one controller to another - iphone

I have a login controller ,and after the successful login i want to pass some string value to the menu page.however it does not work.the application crashes.
I have tried possible suggesstion of Ihuk and SAM from the link below
how to pass a string value from one view controller to another view controller
loginController.h:
#import <UIKit/UIKit.h>
#class RootViewController;
#class Menu;
#interface LoginController : UIViewController {
UIButton *login_Button;
UITextField *username_TextField;
UITextField *password_TextField;
RootViewController *mc1;
UINavigationController *navigationController;
Menu *mv1;
}
#property(nonatomic,retain) IBOutlet UIButton *login_Button;
#property(nonatomic,retain) IBOutlet UITextField *username_TextField;
#property(nonatomic,retain) IBOutlet UITextField *password_TextField;
#property(nonatomic,retain) RootViewController *mc1;
#property (nonatomic, retain) IBOutlet
UINavigationController *navigationController;
#property(nonatomic,retain)Menu *mv1;
- (IBAction)Login_Method:(id)sender;
-(id)initWithUserName:(NSString *)name ;
#end
loginController.m
#import "LoginController.h"
#import "Menu.h"
#import "ViewController.h"
#import "RootViewController.h"
#implementation LoginController
#synthesize mc1,mv1;
#synthesize login_Button,username_TextField,password_TextField;
#synthesize navigationController;
// Implement viewDidLoad to do additional setup after
// loading the view, typically from a nib.
- (void)viewDidLoad {
if (![self.navigationController isNavigationBarHidden])
[self.navigationController setNavigationBarHidden:YES animated:NO];
//[self presentModalViewController:navigationController animated:YES];
}
- (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;
}
- (IBAction)Login_Method:(id)sender
{
Menu *mv2 = [[Menu alloc] initWithUserName:#"Menu" bundle:nil];
//mv2.l1.text=#"aa"; //i tried this, but not work,so created initWithUserName
self.mv1=mv2;
[self presentModalViewController:mv1 animated:YES];
// [RootViewController release];
}
-(id)initWithUserName:(NSString *)name
{
self = [super init];
if (nil == self) {
return nil;
}
// display or store login info somewhere
[mv1.l1 setText:name];
return self;
}
-(BOOL)textFieldShouldReturn:(UITextField *)theTextField {
[theTextField resignFirstResponder];
return YES;
}
- (void)dealloc {
[username_TextField release];
[password_TextField release];
[super dealloc];
}
#end
Menu.h
#import <UIKit/UIKit.h>
#class Menu;
#interface Menu : UIViewController {
UILabel *l1;
UIButton *AccountSummary_Button;
UIButton *PayOffQuote_Button;
UIButton *PayBill_Button;
UIButton *Logout_Button;
UINavigationController *nv1;
}
#property(nonatomic,retain) IBOutlet UILabel *l1;
#property(nonatomic,retain) IBOutlet UIButton *AccountSummary_Button;
#property(nonatomic,retain) IBOutlet UIButton *PayOffQuote_Button;
#property(nonatomic,retain) IBOutlet UIButton *PayBill_Button;
#property(nonatomic,retain) IBOutlet UIButton *Logout_Button;
#property (nonatomic, retain) IBOutlet UINavigationController *nv1;
-(IBAction)ViewAccountSummary_method:(id)sender;
-(IBAction)ViewPayOffQuote_method:(id)sender;
-(IBAction)ViewPayBill_method:(id)sender;
-(IBAction)Logout_method:(id)sender;
#end
Menu.m

Make a property in your application delegate, for example, an NSString* called myString.
Then access it from the login controller and other controllers like so:
[[UIApplication sharedApplication] delegate].myString
You could, for example, set myString's value in the login controller:
[[UIApplication sharedApplication] delegate].myString = #"value";
You could read it in any other controller:
NSLog(#"myString is: %#", [[UIApplication sharedApplication] delegate].myString);
Additionally, some Cocoa style tips:
Do not capitalize class members (AccountSummary_Button etc.)
Do not capitalize class methods (ViewAccountSummary_method etc.)
The only thing you should capitalize are the classes themselves (Menu etc.).

Related

Issue with UIButton Subclass delegate method

Here is the situation. I have a view controller titled "MyViewController." Within this view controller I have a text editing feature that uses subclassed buttons. The name of the UIButton Subclass is "ColorSwatch"
I have setup delegate/protocol methods in the "ColorSwatch.h" subclass as follow.
// ColorSwatch.h
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import <QuartzCore/QuartzCore.h>
#protocol ColorSwatchDelegate <NSObject>
- (void)fontColor:(UIColor *)color;
#end
#interface ColorSwatch : UIButton {
id <ColorSwatchDelegate> colorSwatchDelegate;
CAGradientLayer *gradient;
UIView *currentView;
UIColor *fontColor;
}
#property (nonatomic, retain) id <ColorSwatchDelegate> colorSwatchDelegate;
#property (nonatomic, retain) CAGradientLayer *gradient;
#property (nonatomic, retain) UIView *currentView;
#property (nonatomic, retain) UIColor *fontColor;
#end
Now in my "ColorSwatch.m" I have:
// ColorSwatch.m
#import "ColorSwatch.h"
#import <QuartzCore/QuartzCore.h>
#import "MyViewController.h"
#implementation ColorSwatch
#synthesize gradient;
#synthesize currentView;
#synthesize colorSwatchDelegate;
#synthesize fontColor;
-(void)setupView{
"Makes the subclassed buttons pretty"
}
-(id)initWithFrame:(CGRect)frame{
if((self = [super initWithFrame:frame])){
}
return self;
}
-(id)initWithCoder:(NSCoder *)aDecoder{
if((self = [super initWithCoder:aDecoder])){
[self setupView];
MyViewController *mvc = [[MyViewController alloc] initWithNibName:
#"MyViewController" bundle:nil];
self.colorSwatchDelegate = mvc;
}
return self;
}
-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[self magnify:view];
fontColor = view.backgroundColor;
[self.colorSwatchDelegate fontColor:fontColor];
}
- (void)magnify:(UIView *)view
{
}
- (void)dealloc
{
[currentView release];
[gradient release];
[fontColor release];
[super dealloc];
}
#end
In the "MyViewController.h" I have:
// MyViewController.h
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#import "ColorSwatch.h"
#interface MyViewController : UIViewController <ColorSwatchDelegate> {
UITextField *photoLabelTextField;
}
#property (nonatomic, retain) IBOutlet UITextField *photoLabelTextField;
#end
In the "MyViewController.m" I have:
- (void)fontColor:(UIColor *)color
{
NSLog(#"Selected Font Color");
[self.photoLabelTextField setTextColor:color];
}
Now the delegate method sort of works, meaning when I tap on a color button the
NSLog(#"Selected Font Color");
message gets fired. But the problem is that I cannot change the
[self.photoLabelTextField setTextColor:color];
property. I have tried numerous ways of changing the property, the only thing that I can do is send NSLogs, anything I try to change a property in the "MyViewController" Class nothing happens.
If anyone could please help me out, I would appreciate it.
Thank you
The problem is that the ColorSwatch is sending delegate messages to a dangling instance of MyViewController that it incorrectly allocated in it's initWithCoder: method.
UIControls shouldn't allocate ViewControllers to be their delegates... it goes the other way around.
Delete these lines...
// in ColorSwatch.m initWithCoder:
MyViewController *mvc = [[MyViewController alloc] initWithNibName:
#"MyViewController" bundle:nil];
self.colorSwatchDelegate = mvc;
Then, in MyViewController.m ...
- (void)viewDidLoad {
ColorSwatch *colorSwatchButton = [[ColorSwatch alloc] buttonWithType:UIButtonTypeCustom];
// or place a ColorSwatch in the xib, on MyViewController's view... But not before you
// you delete lines from initWithCoder, otherwise it's infinite circular allocation
colorSwatchButton.frame = CGRectMake(/* ... */);
colorSwatchButton addTarget:self action:#selector(csButtonPressed:) forControlEvent: UIControlEventTouchUpInside];
// and so on...
// now the important part:
colorSwatchButton.colorSwatchDelegate = self;
// see - the ViewController is in charge of allocation, sets itself up as the delegate
[self.view addSubview:colorSwatchButton];
}
Instead of building the button in code, you can use IB.
Step 1: make the delegate an outlet...
#property (nonatomic, retain) IBOutlet id <ColorSwatchDelegate> colorSwatchDelegate;
Step 2: draw the buttons in IB, and set their class to ColorSwatch.
Then you can skip the code I wrote in viewDidLoad.
Step 3: The newly placed button should now present an outlet in IB. You can drag from that to the MyViewController as you normally do.
There might be a connection problem in your IBOutlet photoLabelTextField, you may have forgotten to connect xib text field with your photoLabelTextField

Changed nib File to a OPGL ES View, Buttons don't work

Hy,
There is no problmen with changing the nib but when I'm in the nib-File with the OPGL ES view my buttons that are integrated in this view won't work. When I press one the application crashes.
This is the Code how I change the View to the Second Nib:
- (IBAction)drawEAGLView:(id)sender {
NSArray* nibViews = [[NSBundle mainBundle] loadNibNamed:#"settingsViewController" owner:self options:nil];
EAGLView* glView = [ nibViews objectAtIndex: 1];
self.view = glView;
[glView startAnimation];}
The Animation is working .
This is the Code of the ViewController where the Button is declared:
SettingsViewController.h:
#import <UIKit/UIKit.h>
#interface SettingsViewController : NSObject {
IBOutlet UIButton *wowButton;
}
#property(nonatomic,retain) IBOutlet UIButton *wowButton;
- (IBAction)wowButtonPressed:(id)sender;
int testvarAnimation;
int animNext;
#end
SettingsViewController.m:
#import "SettingsViewController.h"
#implementation SettingsViewController
#implementation SettingsViewController
#synthesize wowButton;
- (IBAction)wowButtonPressed:(id)sender{
NSLog(#"TOUCHED");
//testvarAnimation = 1;
animNext =1;
}
- (void)dealloc {
[wowButton release];
[super dealloc];
}
#end
Here I show you how I connected the Functions and the Outlets:
http://s3.imgimg.de/uploads/screenshotConna91ea645png.png
Please tell me If you need more informations.
Thanks
Hy I solved my problem, I rewrote my drawEAGLView Methode:
- (IBAction)drawEAGLView:(id)sender {
SettingsViewController *sViewController = [[SettingsViewController alloc] initWithNibName:#"SettingsViewController" bundle:nil];
[[self.view superview] addSubview:sViewController.view];
}
I also corrected my SettingsViewController.h:
#import <UIKit/UIKit.h>
#class EAGLView;
#interface SettingsViewController : UIViewController {
IBOutlet UIButton *wowButton;
EAGLView *glview;
}
#property(nonatomic,retain) IBOutlet UIButton *wowButton;
#property (nonatomic, retain) IBOutlet EAGLView *glView;
- (IBAction)wowButtonPressed:(id)sender;
int testvarAnimation;
int animNext;
#end
And last but not least I changed my SettingsViewController.m:
#import "SettingsViewController.h"
#import "EAGLView.h"
#implementation SettingsViewController
#synthesize wowButton, glView;
- (IBAction)wowButtonPressed:(id)sender{
NSLog(#"TOUCHED");
//testvarAnimation = 1;
animNext =1;
}
- (void)viewDidLoad {
glView.animationInterval = 1.0 / 60.0;
[glView startAnimation];
[super viewDidLoad];
}
- (void)dealloc {
[wowButton release];
[super dealloc];
}
#end
I also changed my Nib file. I removed the ViewController and set the type of the File's Owner to my viewController named "SettingsViewController". I connected the File's Owner Outlet view with the EAGLView and the button with the SettingsViewControllers wowButtonPressed Method
I hope I could help also someone else,
Thanks
Here is the right solution for this problem:
First you have to create a parnet object of your view you want to be shown as first.
You need to do this in the header file of the second view.
//
// SettingsViewController.h
// NeheTutorial2
//
// Created by Global Sound on 05.04.11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import <UIKit/UIKit.h>
#class EAGLView;
#class mobilesynthViewController;
#interface SettingsViewController : UIViewController {
IBOutlet UIButton *wowButton;
IBOutlet UIButton *optiButton;
EAGLView *glView;
//mobilesynthViewController *mViewController;
mobilesynthViewController *parent;
}
#property(nonatomic,retain) IBOutlet UIButton *wowButton;
#property(nonatomic,retain) IBOutlet UIButton *optiButton;
#property (nonatomic, retain) IBOutlet EAGLView *glView;
//#property(nonatomic,retain) IBOutlet mobilesynthViewController *mViewController;
#property (nonatomic, retain) mobilesynthViewController *parent;
- (IBAction)wowButtonPressed:(id)sender;
- (IBAction)optiButtonPressed:(id)sender;
int testvarAnimation;
int animNext;
int musicOn;
int isAnimating;
float zaehler;
#end
Now in the implemetaion File you need to add the parent object to your function:
#import "SettingsViewController.h"
#import "EAGLView.h"
//#import "mobilesynthViewController.h"
#implementation SettingsViewController
#synthesize wowButton, optiButton, glView;//,mViewController;
#synthesize parent;
- (IBAction)wowButtonPressed:(id)sender{
NSLog(#"TOUCHED");
[parent startThread];
[parent showbButtonStop];
testvarAnimation = 0;
animNext =1;
//musicOn =1;
}
- (IBAction)optiButtonPressed:(id)sender{
NSLog(#"OPTIONS ON");
[self dismissModalViewControllerAnimated:YES];
[parent showbButton];
//mobilesynthViewController *aRootViewController = [[mobilesynthViewController alloc] initWithNibName:#"mobilesynthViewContoller" bundle:nil];
//[self setRootViewController:aRootViewController];
//[aRootViewController release];
//mobilesynthViewController *mViewController = [[mobilesynthViewController alloc] initWithNibName:#"mobilesynthViewController" bundle:nil];
//[[self.view superview] addSubview:mViewController.view];
//self.view = mViewController;
//CGRect rect = [[UIScreen mainScreen] applicationFrame];
//mViewController = [[mobilesynthViewController alloc] initWithFrame:CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height)];
//self.view = mViewController;
}
- (void)viewDidLoad {
glView.animationInterval = 1.0 / 60.0;
[glView startAnimation];
[super viewDidLoad];
}
/*
- (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 {
[wowButton release];
[optiButton release];
[super dealloc];
}
#end
In my case I'm calling a other function in the main View of my program. When the button in the second view is pressed the function in the first view is called through the the parent object
[parent startThread];
Again the startThread methode was declerated in another view.
I hope I could help you.

change a label from another view

I have a label on my main View. I have a button which brings me to another view. On it I have a button to change my label which is on the main view.
How can I do this? I included a projet, could someone help me please...
I usually use a delegate protocol:
in the second view h add :
#protocol viewControllerDelegate;
#interface viewController : UIView
id < viewControllerDelegate > delegate;
#property (nonatomic, assign) id < QuickViewControllerDelegate > delegate;
#end
#protocol viewControllerDelegate
- (void)viewController:(ViewController *)controller stringForLabel:(NSString*)string;
#end
in the second view m file call:
[delegate quickViewController:self
stringForLabel:#"your string"];
in the main view h file add: , like that:
#interface MainView:UIViewController<viewControllerDelegate>
in the main view m file:
first: when you init the second view don't forget to add:
secondview.delegate = self;
other wise it wont work.
second: add the delegate function:
- (void)viewController:(ViewController*)controller stringForLabel:(NSString*)string{
//set the label from the string passed
lable.text = string;
}
hope it will help
shani
O.K i usually don't do that but for now...
this are your files after i have change them -
View1 .h (try to name those files with a capital letter);
#import <UIKit/UIKit.h>
#protocol View1Delegate;
#interface View1 : UIViewController {
id <View1Delegate> delegate;
IBOutlet UIButton *btn_changelbl;
IBOutlet UIButton *btn_back;
}
#property (nonatomic, assign) id <View1Delegate> delegate;
#property (nonatomic,retain) IBOutlet UIButton *btn_changelbl;
#property (nonatomic,retain) IBOutlet UIButton *btn_back;
-(IBAction) backToMain:(id)sender;
-(IBAction) changeLabel:(id)sender;
#end
#protocol View1Delegate
- (void)view1:(View1*)controller labelNeedsChage:(BOOL)needsChange stringForLabel:(NSString*)string;
#end
View1.m
#import "View1.h"
#import "testViewController.h"
#implementation View1
#synthesize delegate;
#synthesize btn_changelbl;
#synthesize btn_back;
-(IBAction) backToMain:(id)sender {
[self dismissModalViewControllerAnimated:YES];
[delegate view1:self labelNeedsChage:NO stringForLabel:nil];
}
-(IBAction) changeLabel:(id)sender{
[delegate view1:self labelNeedsChage:YES stringForLabel:#"new text"];
[self dismissModalViewControllerAnimated:YES];
}
- (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 {
[super viewDidUnload];
}
- (void)dealloc {
[btn_changelbl release];
[btn_back release];
[super dealloc];
}
#end
TestViewController.h
#import <UIKit/UIKit.h>
#import "View1.h"
#interface testViewController : UIViewController<View1Delegate> {
IBOutlet UILabel *lb_test;
IBOutlet UIButton *btn_changeView;
}
#property (nonatomic,retain) IBOutlet UILabel *lb_test;
#property (nonatomic,retain) IBOutlet UIButton *btn_changeView;
-(IBAction) changeView:(id)sender;
#end
TestViewController.m
#import "testViewController.h"
#import "view1.h"
#implementation testViewController
#synthesize lb_test;
#synthesize btn_changeView;
-(IBAction) changeView:(id)sender {
View1 *myView = [[View1 alloc] init];
myView.delegate=self;
[self presentModalViewController:myView animated:YES];
}
- (void)view1:(View1*)controller labelNeedsChage:(BOOL)needsChange stringForLabel:(NSString*)string{
if(needsChange){
lb_test.text=string;
}
}
- (void)dealloc {
[lb_test release];
[btn_changeView release];
[super dealloc];
}
#end
Thats it.
by the way:
you had many small mistakes that i have fixed. look at the fixes to try to understand them.

How to pass a variable from one view controller to another?

I have three view controllers, one root controller, one login view controller and one customers view controller. I want to pass the entered username and password in login view controller to the customers view controller. My files and code is displayed below, could you please guide me, how can access to variables set in the login view controller? Or how can I pass variables to customers view controller?
I have these class files:
/classes/MySoftwareAppDelegate.h
/classes/MySoftwareAppDelegate.m
/classes/ViewController.h
/classes/ViewController.m
/classes/LoginController.h
/classes/LoginController.m
/classes/CustomersController.h
/classes/CustomersController.m
I have these views:
/resources/MainWindow.xib
/resources/Login.xib
/resources/Customers.xib
In the AppDelegate, I have successfully inserted the sub view "Login" and it's displayed whenever the app starts.
In the login view, I enter my username and password and then click the "Login" button. When this button is clicked, an IBAction is triggered. In this IBAction, I want to change the current subview with the Customers.
Here's the code I have used:
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
As you can see above, in LoginController.m's loginToAccount method, I am checking the login info and then setting the new view controller for the "customers" sub-view.
Then I am removing the current "Login" subview from the super view but don't know how to add the new "Customers" sub view.
In MainWindow.xib, I have one view controller which is linked to ViewController class and it's the root contoller.
Any help is appreciated. Because I am new to Objective-C and iPhone programming, please do your best to explain considering a novice programmer :)
Thanks again.
Okay, let me answer my question. I just found the answer on StackOverFlow.com
In the view controller which is going to load the next view controller, just add these lines:
NextController *tmpViewController = [[NextController alloc] initWithNibName:#"NextView" bundle:nil];
tmpViewController.enteredUsername = usernameTextField.text;
tmpViewController.enteredPassword = passwordTextField.text;
I'd say that better way is to have separate class for storing globally needed data (and that would be compliant with MVC model).
For example you can store you login information in your MySoftwareAppDelegate, which is easily accessible with [[UIApplication sharedApplication] delegate] call from any part of your application.
It all depends on how serious the data you want to pass it. For a quick variable (maybe a settings change in a modal view controller) TamTam's solution makes the most sense. You alloc/init'ed it, you got the variable, why not access it properties? That same (modally presented) view controller might pass variables back via a delegate pattern.
If you're data needs to be system wide, you can use the singleton pattern. Using "[[UIApplication sharedApplication] delegate]" gets the application delegation (which is a singleton), and many people stuff their variables there for convenience. However, your app delegate wasn't designed for this, and so it's considered bad form. Create your own singleton if your apple isn't a quickie.
If you use a persistent data store like sql, plists or coredata, you can put your system wide data there.

Having problem with view switching from a subview

Maybe this is a silly question but I'm having a problem with switching the view in a subview. Let me explain the code structure:
I have these class files:
/classes/MySoftwareAppDelegate.h
/classes/MySoftwareAppDelegate.m
/classes/ViewController.h
/classes/ViewController.m
/classes/LoginController.h
/classes/LoginController.m
/classes/CustomersController.h
/classes/CustomersController.m
I have these views:
/resources/MainWindow.xib
/resources/Login.xib
/resources/Customers.xib
In the AppDelegate, I have successfully inserted the sub view "Login" and it's displayed whenever the app starts.
In the login view, I enter my username and password and then click the "Login" button. When this button is clicked, an IBAction is triggered. In this IBAction, I want to change the current subview with the Customers.
Here's the code I have used:
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.view removeFromSuperview];
[tmpViewController release];
}
#end
As you can see above, in LoginController.m's loginToAccount method, I am checking the login info and then setting the new view controller for the "customers" sub-view.
Then I am removing the current "Login" subview from the super view but don't know how to add the new "Customers" sub view.
In MainWindow.xib, I have one view controller which is linked to ViewController class and it's the root contoller.
Any help is appreciated. Because I am new to Objective-C and iPhone programming, please do your best to explain considering a novice programmer :)
Thanks again.
You are not adding any views to the view hierarchy, just removing the login view controller. If you want to add your customer view to the view hierarchy you should use:
CustomersController *tmpViewController = [[CustomersController alloc] initWithNibName:#"Customers" bundle:nil];
self.customersController = tmpViewController;
[self presentModalViewController:tmpViewController]
The above method will make sure that the viewWillLoad, didLoad etc are called on the account view controller. It will also take care of removing and adding the correct views to the view hierarchy for you.