Objective-C setting the delegate for a collection - iphone

I'm trying to set the delegate to be my UITextfield collection so that I can call resignFirstResponder on all of my textfields. What I've tried has not responded.
#property (nonatomic, weak) IBOutletCollection(UITextField) NSMutableArray *textFields;
- (void)viewDidLoad
{
[_textFields enumerateObjectsUsingBlock:^(UITextField *textfield, NSUInteger idx, BOOL *stop)
{
textfield.delegate=self;
}];
}
- (BOOL) textFieldShouldReturn:(UITextField *)textFields
{
NSLog(#"textFieldShouldReturn Fired :)");
[_textFields enumerateObjectsUsingBlock:^(UITextField *textfield, NSUInteger idx, BOOL *stop)
{
[textfield resignFirstResponder];
}];
return YES;
}

Did you add UITextFieldDelegate in the .h?
#interface MyVC : UIViewController <UITextFieldDelegate>
Also maybe try:
for (UITextField __strong *field in self.textFields)
field.delegate = self;

Related

Why is my tableView not displaying objects?

First of I would like to start with I am 100% new to iPhone development. I believe this is a quite simple question for someone experienced. Anyhow, what I am trying to do is:
The user should via the SearchUI be able to search for objects from my database. If the object exist, display it in the tableView where the search-objects will be displayed. I manage to get the objects from the database but not instance them into the tableview and display them.
Honestly I don't know what I am doing wrong. All help will be really appreciated and also some explaining if possible. Under method - (void)objectLoader:(RKObjectLoader *)objectLoader didLoadObjects:(NSArray *)objects - I try to move the objects into the tableView without any success. You find the method in FirstViewController.m at the end of pragma mark TableView Data Scource methods. Here is my code:
FirstViewController.h class
#import <UIKit/UIKit.h>
#import <RestKit/RestKit.h>
#interface FirstViewController : UIViewController <UITableViewDataSource, RKObjectLoaderDelegate>
{
UISearchDisplayController *searchDisplayController;
UISearchDisplayController *searchBar;
UITableView *table;
NSArray *allItems;
NSArray *searchResults;
}
#property (nonatomic, retain) IBOutlet UISearchDisplayController *searchDisplayController;
#property (nonatomic, retain) IBOutlet UISearchDisplayController *searchBar;
#property (nonatomic, retain) IBOutlet UITableView *table;
#property (nonatomic, copy) NSArray *allItems;
#property (nonatomic, copy) NSArray *searchResults;
#end
FirstViewController.m class
#import "FirstViewController.h"
#import "Task.h"
interface FirstViewController ()
end
implementation FirstViewController
#synthesize searchDisplayController;
#synthesize searchBar;
#synthesize allItems;
#synthesize searchResults;
#synthesize table;
#pragma mark - View lifecycle
- (void)viewDidLoad
{
//self.listContent = [[NSArray alloc] initWithObjects:#"John", #"Paul", nil];
//self.filteredListContent = [NSMutableArray arrayWithCapacity:10];
[super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
else
{
return YES;
}
}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
return NO;
}
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption
{
return NO;
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)pSearchBar
{
[[RKObjectManager sharedManager].mappingProvider setMapping:[Task getMapping] forKeyPath:#"tasks"];
NSString *path = [NSString stringWithFormat:#"%#/%#/%#", #"/book/1/tasks/", pSearchBar.text, #".json"];
[[RKObjectManager sharedManager] loadObjectsAtResourcePath:path delegate:self];
NSLog(#"Search: %#", pSearchBar.text);
}
#pragma mark - TableView Data Scource methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.searchResults count];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
{
UITableViewCell *cell = nil;
cell = [tableView dequeueReusableCellWithIdentifier:#"MyCell"];
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"MyCell"];
}
cell.textLabel.text = [self.searchResults objectAtIndex:indexPath.row];
return cell;
}
- (void) deselect {
//[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
}
// Respond to user selection tap by coloring the navigation bar
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)newIndexPath
{
}
- (void)objectLoader:(RKObjectLoader *)objectLoader didLoadObjects:(NSArray *)objects
{
self.searchResults = objects;
[self.table reloadData];
for(Task *task in objects)
{
if ([task isKindOfClass:[Task class]])
{
NSLog(#"Loaded Book ID: %# ; Name: %# ; Book: %#", task.id, task.name, task.book.name);
}
}
}
- (void)objectLoader:(RKObjectLoader *)objectLoader didFailWithError:(NSError *)error
{
NSLog(#"Encountered an error: %#", error);
}
#end
Step1. Since your TableView is an IBOutlet, check you tableView datasource and delegate mappings in the .xib file for this view controller. My doubt is that the hooking is not correct.
Step2. If the hook ups in .xib file are correct, then you should do
- (void)objectLoader:(RKObjectLoader *)objectLoader didLoadObjects:(NSArray *)objects
{
self.searchResults = objects;
NSLog(#"%#", searchResults)
[self.table reloadData];
....
}
and check if the NSLog is logging the searchResults array. If that's empty for some reason, your numberOfRowsInSection delegate method will return 0 and hence your tableView will be empty.
Hope this helps.
in the first line
#interface FirstViewController : UIViewController <UITableViewDataSource, RKObjectLoaderDelegate>
{
UISearchDisplayController *searchDisplayController;
UISearchDisplayController *searchBar;
UITableView *table;
NSArray *allItems;
NSArray *searchResults;
}
replace this line with below code
#interface FirstViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, RKObjectLoaderDelegate>
{
UISearchDisplayController *searchDisplayController;
UISearchDisplayController *searchBar;
IBOutlet UITableView *table;
NSArray *allItems;
NSArray *searchResults;
}
and connect the tableview delegate and tableview datasource in interface builder.
Hope it helps.

How to save data of the custom cell textfields?

i am new to the iPhone development, i am developing an app were i have tableview with custom-cell,my custom-cell contains label and textfiled. this is my registration screen,How to save the data of my textfields and,how to do validations for the text. In the textfield endediting we can save the data. but if the user on the first filed enter name and then he click done button it will show please enter first name, because i am saving data in didendediting. i want to save the data when ever user is on the textfield.
you can use this method to trace your current textfield text, with the help of the model class objects to store your text.
- (BOOL)textField:(UITextField *)theTextField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
NSString *characterSet = nil;
switch (theTextField.tag)
{
case 1:
characterSet = #"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ";
[sharedInstance.registrationDetails setFirstName:theTextField.text];
default:
characterSet = #"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789?/!##$&*.,-:; _";
break;
}
NSCharacterSet *myCharSet = [NSCharacterSet characterSetWithCharactersInString:characterSet];
for (int i = 0; i < [string length]; i++)
{
unichar c = [string characterAtIndex:i];
if (![myCharSet characterIsMember:c])
{
return NO;
}
}
return YES;
}
Make the controller the delegate of the cell's textField and then implement these methods in your controller.
- (void)textFieldDidEndEditing:(UITextField *)textField
{
NSInteger tag = [textField tag];
if(tag == 0) {
//save first name text value
}
else if (tag == 1){
//save last name text value
}
else if etc....
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
Just make sure you set the tag appropriately when you return the cell in
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
You could also do some research on how to get the keyboard to act like a form handler with the next/previous buttons
Register.h
#interface Register : NSObject {
NSString *_firstNameTxt;
NSString *_lastNameTxt;
NSString *_emailTxt;
NSString *_passwordTxt;
}
#property (nonatomic, retain) NSString * firstNameTxt;
#property (nonatomic, retain) NSString * lastNameTxt;
#property (nonatomic, retain) NSString * emailTxt;
#property (nonatomic, retain) NSString * passwordTxt;
#end
Register.m
#implementation Register
#synthesize firstNameTxt=_firstNameTxt;
#synthesize lastNameTxt =_lastNameTxt ;
#synthesize emailTxt=_emailTxt;
#synthesize passwordTxt= _passwordTxt;
- (void)dealloc{
[super dealloc];
[_firstNameTxt release];
[_lastNameTxt release];
[_emailTxt release];
[_passwordTxt release];
}
#end
RegisterViewController.h
#class Register;
#interface RegisterViewController : UIViewController {
Register *objRegister;
}
RegisterViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
objRegister = [[Register alloc] init];
}
tableview delegates
[txtFirstName setText:objRegister.firstNameTxt];
[txtLastName setText:objRegister.lastNameTxt];
-(void) textFieldDidEndEditing:(UITextField *)textField{
// do the same code as Warren Burton Post
}

Passing Values Between Master and Detail in UISplitViewController Using Storyboards

I have defined the protocol in Customer.h file which is shown below:
#class Customer;
#protocol CustomerDelegate <NSObject>
-(void) didSelectCustomer:(Customer *) customer;
#end
#interface Customer : NSObject
{
}
#property (nonatomic,copy) NSString *name;
#property (nonatomic,copy) NSString *occupation;
#end
The MasterViewController (left side) invokes the didSelectCustomer method as shown below:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
Customer *selectedCustomer = [customers objectAtIndex:[indexPath row]];
[self.delegate didSelectCustomer:selectedCustomer];
}
Now, I need to tell the DetailViewController (right side) to do something. The DetailViewController complies with the CustomerDelegate protocol.
#interface DetailViewController : UIViewController<UISplitViewControllerDelegate,CustomerDelegate>
{
}
-(void) didSelectCustomer:(Customer *)customer
{
NSLog(#"sssdasdasdasd");
}
The didSelectCustomer method is never invoked. I think I need to set the masterViewController.delegate = self but I am not sure where to set this thing up.
UPDATE 1:
I added the instance of MasterViewController inside the DetailViewController but it did not work:
- (void)viewDidLoad
{
[super viewDidLoad];
MasterViewController *master = [[MasterViewController alloc] init];
master.delegate = self;
}
SOLUTION:
In AppDelegate:
else
{
UISplitViewController *splitViewController = (UISplitViewController *) self.window.rootViewController;
splitViewController.delegate = [splitViewController.viewControllers lastObject];
UINavigationController *navigationController = [splitViewController.viewControllers lastObject];
// splitViewController.delegate = (id)navigationController.topViewController;
DetailViewController *detail =(DetailViewController *) [splitViewController.viewControllers lastObject];
UINavigationController *masterNavigationController = [splitViewController.viewControllers objectAtIndex:0];
MasterViewController *master = (MasterViewController *)masterNavigationController.topViewController;
master.delegate = detail;
}
You never explicitly declare yourself as the delegate to the Consumer class. Merely conforming to it won't cut it. Declare it in -viewDidLoad by creating an instance of Consumer, possibly like this:
-(void)viewDidLoad {
Consumer *consumer = [[Consumer alloc]init];
[consumer setDelegate:self];
}
You also don't declare a property for your delegate object in Consumer, so it can never actually be accessed. Do this first:
#class Customer;
#protocol CustomerDelegate <NSObject>
-(void) didSelectCustomer:(Customer *) customer;
#end
#interface Customer : NSObject
{
}
#property (nonatomic,copy) NSString *name;
#property (nonatomic,copy) NSString *occupation;
#property (weak) id <CustomerDelegate> delegate; //use assign or __unsafe_unretained if targeting <5.0.
#end
You can check if your class conforms to your protocol like so:
if (![delegate conformsToProtocol:#protocol(CustomerDelegate)]) {
[NSException raise:#"Delegate Exception"
format:#"Parameter does not conform to CustomerDelegate protocol at line %d", (int)__LINE__];
}
the split view controller's last object.
this object is return a UI navigation controller.
you know, then you can do yourself.

Custom UITableViewCells

I am actually very surprised how difficult it is to keep your code well structured and readable when doing iphone app stuff... but it might be because I am doing something wrong.
I have a Sign Up page containing different kinds of inline-editable data: birthday, gender, name, password, phone number. I have made the page as a table view of custom cells where each cell is an instance of a sub class of UITableViewCell and is read from its own nib file. This because I thought that I then might be able to reuse these different kinds of cells later in other table view pages.
The approach of encapsulating the different custom cells in their own place is not working that well though:
Who is going to be the controller of e.g the gender picker inside the GenderCell?
How am I actually going to reuse the cells in a different table view controller when I had to put the SignUpController as the file's owner of the cell nib files?
I do not know if anyone but myself understood what I just wrote, but if so, I would be very thankful for any suggestions on how to structure my code differently.
Thanks a lot,
Stine
To make things more clear (?!) let me paste some of my code in here:
EditableLabel.h
#interface EditableLabel : UILabel {
UIView *inputView, *inputAccessoryView;
}
#property (nonatomic, retain) UIView *inputView, *inputAccessoryView;
- (void) setInputView:(UIView *)aView andToolbar:(UIToolbar *)aToolbar;
#end
EditableLabel.m
#implementation EditableLabel
#synthesize inputView, inputAccessoryView;
- (void) dealloc {
[inputView release];
[inputAccessoryView release];
[super dealloc];
}
- (void) setInputView:(UIView *)aView andToolbar:(UIToolbar *)aToolbar {
self.inputAccessoryView = aToolbar;
self.inputView = aView;
}
- (BOOL) canBecomeFirstResponder {
return YES;
}
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[self becomeFirstResponder];
}
#end
EditableCell.h
typedef enum {
USERNAME, PASSWORD, MOBILE, BIRTHDAY, GENDER, DESCRIPTION, CATEGORY
} CellTag;
#interface EditableCell : UITableViewCell {
CellTag tag;
UIView *editPoint;
IBOutlet UILabel *headerLabel;
}
- (void) setTag:(CellTag)aTag andHeader:(NSString *)aHeader andEditPoint:(UIView *)aView;
#property (nonatomic) CellTag tag;
#property (nonatomic, retain) UIView *editPoint;
#property (nonatomic, retain) UILabel *headerLabel;
- (IBAction) editingDone:(id)sender;
- (void) showInputView;
- (void) hideInputView;
#end
EditableCell.m
#implementation EditableCell
#synthesize tag, editPoint, headerLabel;
- (void) dealloc {
[editPoint release];
[headerLabel release];
[super dealloc];
}
- (void) setTag:(CellTag)aTag andHeader:(NSString *)aHeader andEditPoint:(UIView *)aView {
self.tag = aTag;
self.headerLabel.text = aHeader;
self.editPoint = aView;
}
- (IBAction) editingDone:(id)sender {
[self hideInputView];
}
- (void) showInputView {
[self.editPoint becomeFirstResponder];
}
- (void) hideInputView {
[self.editPoint resignFirstResponder];
}
#end
EditableLabelCell.h
#interface EditableLabelCell : EditableCell {
IBOutlet UILabel *placeHolderLabel;
IBOutlet EditableLabel *editableLabel;
}
#property (nonatomic, retain) UILabel *placeHolderLabel;
#property (nonatomic, retain) EditableLabel *editableLabel;
- (void) setTag:(CellTag)aTag
andHeader:(NSString *)aHeader
andPlaceHolder:(NSString *)aPlaceHolder
andInputView:(UIView *)aView
andToolbar:(UIToolbar *)aToolbar;
- (void) setValue:(NSString *)aValue;
#end
EditableLabelCell.m
#implementation EditableLabelCell
#synthesize placeHolderLabel, editableLabel;
- (void) dealloc {
[placeHolderLabel release];
[editableLabel release];
[super dealloc];
}
- (void) setTag:(CellTag)aTag andHeader:(NSString *)aHeader andPlaceHolder:(NSString *)aPlaceHolder andInputView:(UIView *)aView andToolbar:(UIToolbar *)aToolbar {
[super setTag:aTag andHeader:aHeader andEditPoint:self.editableLabel];
self.placeHolderLabel.text = aPlaceHolder;
[self.editableLabel setInputView:aView andToolbar:aToolbar];
}
- (void) setValue:(NSString *)aValue {
if (aValue && aValue != #"") {
self.placeHolderLabel.hidden = YES;
self.editableLabel.text = aValue;
} else {
self.editableLabel.text = nil;
self.placeHolderLabel.hidden = NO;
}
}
#end
EditableGenderCell.h
#protocol EditableGenderCellDelegate <NSObject>
#required
- (NSString *) getTextForGender:(Gender)aGender;
- (void) genderChangedTo:(Gender)aGender forTag:(CellTag)aTag;
#end
#interface EditableGenderCell : EditableLabelCell <UITableViewDataSource, UITableViewDelegate> {
id<EditableGenderCellDelegate> delegate;
Gender gender;
IBOutlet UITableView *genderTable;
IBOutlet UIToolbar *doneBar;
}
- (void) setTag:(CellTag)aTag
andDelegate:(id<EditableGenderCellDelegate>)aDelegate
andHeader:(NSString *)aHeader
andGender:(Gender)aGender
andPlaceHolder:(NSString *)aPlaceHolder;
#property (nonatomic, retain) id<EditableGenderCellDelegate> delegate;
#property (nonatomic) Gender gender;
#property (nonatomic, retain) UITableView *genderTable;
#property (nonatomic, retain) UIToolbar *doneBar;
#end
EditableGenderCell.m
#implementation EditableGenderCell
#synthesize delegate, gender, genderTable, doneBar;
- (void) dealloc {
[delegate release];
[genderTable release];
[doneBar release];
[super dealloc];
}
- (void) setTag:(CellTag)aTag andDelegate:(id<EditableGenderCellDelegate>)aDelegate andHeader:(NSString *)aHeader andGender:(Gender)aGender andPlaceHolder:(NSString *)aPlaceHolder {
[super setTag:aTag andHeader:aHeader andPlaceHolder:aPlaceHolder andInputView:self.genderTable andToolbar:self.doneBar];
self.delegate = aDelegate;
self.gender = aGender;
[super setValue:[self.delegate getTextForGender:aGender]];
}
#pragma mark - Table view data source
- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 2;
}
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
switch (indexPath.row) {
case MALE:
switch (self.gender) {
case MALE:
cell.accessoryType = UITableViewCellAccessoryCheckmark;
break;
default:
cell.accessoryType = UITableViewCellAccessoryNone;
}
break;
case FEMALE:
switch (self.gender) {
case FEMALE:
cell.accessoryType = UITableViewCellAccessoryCheckmark;
break;
default:
cell.accessoryType = UITableViewCellAccessoryNone;
}
break;
}
cell.textLabel.text = [self.delegate getTextForGender:indexPath.row];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
#pragma mark - Table view delegate
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
self.gender = indexPath.row;
[super setValue:[self.delegate getTextForGender:self.gender]];
[self.delegate genderChangedTo:self.gender forTag:self.tag];
[tableView reloadData];
}
#end
Have a look at my answer to How to make a UITableViewCell with different subviews reusable?.
You should back up your custom tableviewcell nib files with a custom class representing your cell and encapsulate logic in it for example your gender picker. If you need to inform some outside controller of the gender you can make use of the delegate pattern.
Custom Gender picker in a TableViewCell
Ok let's start with the nib file, looking like this:
view hierarchy, don't set the File's Owner...
...set instead the class of the table view cell of your custom class:
The custom class
As you can see the class is almost empty, only providing the segmented control as property
GenderPickerTableViewCell.h
#interface GenderPickerTableViewCell : UITableViewCell
{
UISegmentedControl *genderPickerSegmentedControl;
}
#property (nonatomic, retain) IBOutlet UISegmentedControl *genderPickerSegmentedControl;
#end
GenderPickerTableViewCell.m
#import "GenderPickerTableViewCell.h"
#implementation GenderPickerTableViewCell
#synthesize genderPickerSegmentedControl;
#pragma mark -
#pragma mark memory management
- (void)dealloc
{
[genderPickerSegmentedControl release];
[super dealloc];
}
#pragma mark -
#pragma mark initialization
- (void)awakeFromNib
{
// initialization goes here, for example preselect a specific gender
}
#end
The table view using our new cell
I'll provide only the necessary methods to make this work. The TableViewCellFactory class is just a nib loader like I posted in my referenced answer above. The genderPickerTableViewCellWithTableView is just a convenience class method to return that special kind of cell without too much boilerplate code
The last important thing to note is the configuration of the cell, this is kept simple, I just access the segmented control directly and add a target to it which informs this view controller about a change.
#pragma mark -
#pragma mark view lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
tableView.rowHeight = 100.0;
tableView.dataSource = self;
tableView.delegate = self;
}
#pragma mark -
#pragma mark UITableView methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 1;
}
- (UITableViewCell *) tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)anIndexPath
{
GenderPickerTableViewCell *cell = [TableViewCellFactory genderPickerTableViewCellWithTableView:aTableView];
[cell.genderPickerSegmentedControl addTarget:self
action:#selector(genderPicked:)
forControlEvents:UIControlEventValueChanged];
return cell;
}
#pragma mark -
#pragma mark UISegmentedControl action
- (void)genderPicked:(id)sender
{
UISegmentedControl *segmentedControl = (UISegmentedControl *)sender;
NSLog(#"selected index: %d", [segmentedControl selectedSegmentIndex]);
}
I hope this helps a bit for the beginning.
This is the code you can use for bouncing:
-(IBAction)textFieldDidBeginEditing:(UITextField *)textField { //Keyboard becomes visible
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.3];
self.view.frame = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y - 50, self.view.frame.size.width, self.view.frame.size.height);
[UIView commitAnimations];
}
Just set y accordingly an call it when editing begins.

Passing variables from one view to an other

I know this question as been asked over and over but it's still quite obscure to me, so I guess making an example with my code instead will probably be easier .
I know that you can use :
A global variable, ( not good practice ).
Use a delegate
Use a singleton
Say I've got this piece of code here in my first view controller header :
#import <UIKit/UIKit.h>
#interface FirstViewController : UIViewController {
IBOutlet UITextField *Te;
NSInteger evTe;
}
#property (nonatomic, retain) UITextField *Te;
#property (nonatomic) NSInteger evTe;
- (IBAction) makeKeyboardGoAway;
#end
and then this in my implementation file
#import "FirstViewController.h"
#implementation FirstViewController
#synthesize Te;
- (IBAction) makeKeyboardGoAway;
{
[Te resignFirstResponder];
evTe = [Te.text intValue];
}
How would I call evTe in my SecondViewController ? ( maybe using a delegate ?) .
This is what I've got in the second view Controller, header :
#interface SecondViewController : UIViewController {
NSInteger evTe;
}
#property (nonatomic) NSInteger evTe;
and implementation :
- (IBAction) makeKeyboardGoAway;
{
FirstViewController *first = [[FirstViewController alloc] init];
first.evTe = self.evTe;
NSLog(#"second value is %i",evTe);
}
Thanks a lot !
Edit for Tob
FirstViewController.m
- (IBAction) makeKeyboardGoAway;
{
evTe = [Te.text intValue];
NSLog(#"The value of integer num is %i", evTe);
NSDictionary *changedValues = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:evTe] forKey:#"evTe"];
[[NSNotificationCenter defaultCenter] postNotificationName:#"evTeChanged" object:self userInfo:changedValues];
}
SecondViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(methodToCall:) name:#"evTeChanged" object:nil];
}
- (void)methodToCall:(NSNotification *)aNotification{
NSDictionary *changedValues = [[aNotification userInfo] objectForKey:#"evTe"];
NSString *dictionaryString = [changedValues description];
NSLog(#"Notification returning %d",dictionaryString);
}
Unfortunately I'm not getting any log from the SecondView ..
By creating a #property called evTe or whatever in both view controllers.
If the FirstViewController is responsible for creating the SecondViewController you could store the value of evTe in a property in FirstViewController and then after you have created the SecondViewController you set the evTe property there as well.
- (IBAction) makeKeyboardGoAway;
{
[Te resignFirstResponder];
self.evTe = [Te.text integerValue];
}
// other method where SecondViewController is created
SecondViewController* second = [[SecondViewController alloc] init];
second.evTe = self.evTe;
// do what ever
--Edit--
#interface FirstViewController : UIViewController {
IBOutlet UITextField *Te;
NSInteger evTe;
}
#property (nonatomic, retain) UITextField *Te;
#property (nonatomic) NSInteger evTe;
Have a look at NSNotification. You should send a notification that the particular value has changed and register for that notification in the second view controller.
- (IBAction) makeKeyboardGoAway;
{
[Te resignFirstResponder];
evTe = [Te.text intValue];
NSDictionary *changedValues = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:evTe] forKey:#"evTe"];
[[NSNotificationCenter defaultCenter] postNotificationName:#"evTeChanged" object:self userInfo:changedValues];
}
And in the viewDidLoad method of the other controller do:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(methodToCall:) name:#"evTeChanged" object:nil];
Now every time the first controller calls makeKeyboardGoAway the method - (void)methodToCall:(NSNotification *)aNotification will be called.
Implement this method and ask the aNotification for its userInfo which is the NSDictionary you created in the first controller before posting the notification. Get the evTe value out of it and do whatever you want to do with that value.