Pass data back to parent controller for iOS development - ios

i have problem to display selected data into detaillabeltext in one of my row of section, beside reload the whole table view any other method to reload only certain row of section?
//RootViewController.m (parent controller)
-(void) selectedData:(NSString*) text
{
selectedAbsenceType = text;
NSLog(#"the absence type select is %#",text);
}
-(void) (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
if (indexPath.section == 0)
{
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
}
NSDictionary *dictionary = [dataArray objectAtIndex:indexPath.section];
NSArray *array = [dictionary objectForKey:#"data"];
NSString *cellValue = [array objectAtIndex:indexPath.row];
cell.textLabel.text = cellValue;
if([cellValue isEqual: #"Absence Type"])
{
cell.detailTextLabel.text = selectedAbsenceType;
}
else if([cellValue isEqual:#"Start Date"])
{
cell.detailTextLabel.text = selectedDate;
}
return cell;
}
===========================================================================================
i have a problem when i calling the method of the protocol, it keep prompt me a ARC Semantic Issue at this statement
[self.delegate selectedData: (NSString*) [self.absenceTypes objectAtIndex:indexPath.row]];:
//child.h
#import <UIKit/UIKit.h>
#protocol childViewControllerDelegate;
#interface AbsenceTypesViewController : UITableViewController
{
id<childViewControllerDelegate>delegate;
}
#property (nonatomic,weak) id<childViewControllerDelegate> delegate;
#property NSArray *absenceTypes;
#end
#protocol childViewControllerDelegate <NSObject>
-(void) selectedData:(NSString*) text;
#end
//child.m
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *selectedCell = nil;
selectedCell = [self.absenceTypes objectAtIndex:indexPath.row];
[self.delegate selectedData: (NSString*) [self.absenceTypes objectAtIndex:indexPath.row]];
//[self.navigationController popViewControllerAnimated:YES];
NSLog(#"%#", selectedCell);
}

Remove {
id<childViewControllerDelegate>delegate;
} inside user class interface.id<childViewControllerDelegate>delegate; means strong variable which will be released only when holding object is released. But in property declaration you are mentioning delegate as weak property. Hence the ARC Semantic is giving you warning. You can also make the delegate weak by declaring it as weak explicitly like __weak id<childViewControllerDelegate>delegate;
Try replacing the .h file content with this.
#import <UIKit/UIKit.h>
#class AbsenceTypesViewController;
#protocol childViewControllerDelegate <NSObject>
-(void) selectedData:(NSString*) text;
#end
#interface AbsenceTypesViewController : UITableViewController
{
id<childViewControllerDelegate>delegate;
}
#property (nonatomic,weak) id<childViewControllerDelegate> delegate;
#property NSArray *absenceTypes;
#end
So that you have forward declaration of class.

You can save all selected option of second view controller in NSMutable Array and save all components separated by comma and send this array to your parent controller.
NSMutableArray *selectedVal =[[NSMutableArray alloc] init];
FirstViewController *FVC = (FirstViewController*)
if ([FVC isKindOfClass:[FirstViewController class]])
{
[FVC setSelectedOption:[selectedVal componentsJoinedByString:#","]];
}
[self.navigationController popViewControllerAnimated:YES];

Related

How to get back textfield data from tableViewCell in objective c?

I have two tableViewControllers, second tableViewController tableViewCell has textField and imageView, how can I get data from that textfield when I click navigationBarBackButton (I want to store that data in first tableViewController).
// code from second tableViewController...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 0) {
UITableViewCell *cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:#"cellID"];
cell.textLabel.text = #"SIM Name";
cell.detailTextLabel.text = #"AirTel";
cell.imageView.image = [UIImage imageNamed:#"Star2.png"];
return cell;
}
TableViewCell1 *cell1 = [tableView dequeueReusableCellWithIdentifier:#"cell1"];
cell1.nameTextField.delegate = self;
if (indexPath.row == 1) {
NSArray *cell1XibRef = [[NSBundle mainBundle]loadNibNamed:#"TableViewCell1" owner:self options:nil];
cell1 = [cell1XibRef objectAtIndex:0];
cell1.imageView.image = [UIImage imageNamed:#"Con.png"];
self.nameString = cell1.nameTextField.text;
return cell1;
}
return nil;
}
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
return YES;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField{
//Whenever people start editing your textfield
self.nameString = textField.text;
NSLog(#"%#", self.nameString);
}
So many ways to do that but I prefer this way
Save the textfield.text value in NSUserDefaults like this
[[NSUserDefaults standardUserDefaults] setObject:textField.text forKey:#"controllerTwo"];
And get that value in first controller
NSString *secondContrllerText = [[NSUserDefaults standardUserDefaults] stringForKey:#"controllerTwo"];
You can directly add cells in one array and loads cells from that array which will returns you latest cell with all your edits.
NSMutableArray *arrCells = [[NSMutableArray alloc] init];
for (init i=0; i<20; i++){
UITableViewCell *cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:#"cellID"];
arrCells = cell;
}
In cellForRowAtIndexPath method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = arrCell[indexPath.row];
......
return cell;
}
here is the code i like to pass the data with block.here is the code wish to help you.
FirstViewController.h
#import <UIKit/UIKit.h>
#interface FirstViewController : UIViewController
#end
FirstViewController.m
#import "FirstViewController.h"
#import "ViewController.h"
#interface FirstViewController ()
#end
#implementation FirstViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)buttonClick
{
ViewController *controller = [[ViewController alloc] init];
controller.passTheTextFieldData = ^(NSString *textValue){
NSLog(#"show the %# textValue",textValue);
};
[self.navigationController pushViewController:controller animated:YES];
}
#end
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (nonatomic, strong) void (^passTheTextFieldData)();
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()<UITextFieldDelegate>
#property (nonatomic, strong) UITextField *textField;
#property (nonatomic, strong) NSString *textValue;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.textField = [[UITextField alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
[self.textField addTarget:self action:#selector(textFieldValueChanged) forControlEvents:UIControlEventValueChanged];
}
- (void)textFieldValueChanged
{
self.textValue = self.textField.text;
}
- (void)navigationbarBackClick
{
if (self.passTheTextFieldData) {
self.passTheTextFieldData(self.textValue);
}
}
#end
Set the tag property for textField in tableViewCell
Then loop through the cells
for (int i = 0 ; i < [cellDataArray count] ; i++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
UITextField *txtfield = [[cell contentView]viewWithTag:2];
//now get the text txtfield.text
}
Hope this helps
Either you can use delegate method to store your value or use NSUserdefaults.But you have to store one value to pass it to another table view i recommend you to use NSUserdefaults.
//suppose you have to save text (get your data)
NSString *valueToSave = cell1.nameTextField.text;
[[NSUserDefaults standardUserDefaults] setObject:valueToSave forKey:#"keyAbcd"];
[[NSUserDefaults standardUserDefaults] synchronize];
//another page where you want to show your data (paste your data)
NSString *savedValue = [[NSUserDefaults standardUserDefaults]
stringForKey:#"keyAbcd"];//your key have to be same
//print save value in nslog

Passing data from dynamic tableview back to static tableview

Please help i have been struggling passing back the data. I have 2 tableViews. 1st tableview=static table=RootVC. 2nd tableview=dynamic table=FirstVC. in RootVC i have a cell with two labels, "repeatLabel" and "repeatDetail" with a disclosure indicator. When i click on the cell it display the next table which is FirstVC, FistVC is populated with weekdays. after selection of my choice, i want the selected days to be passed back into RootVC in "repeatDetail" and when i go back still be able to see previously selected data.
My RootVC looks like this:
#import "RepeatViewController.h"
#interface SettingsViewController : UITableViewController
#property (strong, nonatomic) IBOutlet UILabel *repeatDetail;
#property (strong, nonatomic) IBOutlet UILabel *repeatLabel;
#property (strong,nonatomic) NSString *getRepeatDetail;
#property (nonatomic, strong) NSMutableArray *selectedDaysArray;
#end
in my RootVC.m
#import "SettingsViewController.h"
#interface SettingsViewController ()
#end
#implementation SettingsViewController
#synthesize repeatLabel,repeatDetail;
#synthesize getRepeatLabel;
#synthesize selectedDaysArray;
- (void)viewDidLoad
{
[super viewDidLoad];
repeatLabel.text = #"Repeat";
repeatDetail.text = getRepeatLabel;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
RepeatViewController *destinationController = segue.destinationViewController;
if( [destinationController isKindOfClass:[RepeatViewController class]] )
{
//You can reuse your selectedDays arrays
destinationController.selectedDays = self.selectedDaysArray;
[(RepeatViewController *)destinationController setCompletionBlock:^(NSArray *retDaysArray) // <- make this change
{
// Save your changes
self.selectedDaysArray = [NSMutableArray arrayWithArray: retDaysArray]; // <- make this change
NSLog(#"retDaysArray: %#", self.selectedDaysArray); //<- Add this debug line
}];
}
}
#end
My 1stVC.h
#import "SettingsViewController.h"
typedef void(^WeekdayCompletionBlock)(NSArray *retDaysArray);
#interface RepeatViewController : UITableViewController <UITableViewDataSource,UITableViewDelegate>
#property (nonatomic,strong) NSMutableArray *selectedDays;
#property (nonatomic, copy) NSArray *completionBlock;
#property (copy) WeekdayCompletionBlock returnBlock;
//#property (strong, nonatomic) IBOutlet UIBarButtonItem *saveButton;
-(IBAction)save:(id)sender;
#end
my 1stVC.m
#import "RepeatViewController.h"
#interface RepeatViewController ()
#end
#implementation RepeatViewController
#synthesize selectedDays= _selectedDays;
#synthesize completionBlock;
#synthesize returnBlock;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
completionBlock = [NSArray arrayWithObjects:#"Sunday", #"Monday", #"Tuesday", #"Wednesday", #"Thursday", #"Friday", #"Saturday", nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return 7;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"RepeatCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier];
}
NSString *day = completionBlock[indexPath.row];
cell.textLabel.text = day;
if ([self.selectedDays containsObject:day])
cell.accessoryType = UITableViewCellAccessoryCheckmark;
else
cell.accessoryType = UITableViewCellAccessoryNone;
//cell.textLabel.text = [completionBlock objectAtIndex:indexPath.row];
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (!self.selectedDays)
self.selectedDays = [[NSMutableArray alloc] init];
if (cell.accessoryType == UITableViewCellAccessoryCheckmark)
{
cell.accessoryType = UITableViewCellAccessoryNone;
//remove data from array
[self.selectedDays removeObject:[completionBlock objectAtIndex:indexPath.row]];
}
else
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
//add data to array
[self.selectedDays addObject:[completionBlock objectAtIndex:indexPath.row]];
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
-(IBAction)save:(id)sender
{
NSUserDefaults *myNewWeekString = [NSUserDefaults standardUserDefaults];
[myNewWeekString setObject:self.selectedDays forKey:#"MY_KEY_FOR_ACCESING_DAYSOFWEEK"];
[myNewWeekString synchronize];
//NSLog(#"The selected day/s is %#",self.selectedDays);
if (self.returnBlock)
{
self.returnBlock(self.selectedDays);
}
[self.navigationController popViewControllerAnimated:YES];
// NSLog(#"The selected day/s is %#",self.selectedDays);
// if (self.returnBlock)
// {
// self.returnBlock([completionBlock objectAtIndex:indexPath.row]);
//}
}
/*
-(void) setReturnBlock:(WeekdayCompletionBlock)returnBlock
{
[self.selectedDays addObject:(self.returnArray);
}
- (NSArray *)setDats
{
return [NSArray arrayWithArray:[self.selectedDays copy]];
}*/
#end
When you work with static cells you have to bind the control you are using directly, there's no need.
So what I can suggest you is the following:
Bind your controls with some specific identifier, like labelFieldRow{rowid} example: labelFieldRow1.
So on prepare for segue, just check what's the selected row and pass the data you want to the destination controller.
Probably not the best, but it should work.
You have to pass data (selected by user before) from your RootVC to FirstVC. To do that in your RootVC add property to keep the selected data;
#property (nonatomic, strong) NSMutableArray *selectedDaysArray;
In prepareForSegue method you have to pass that array to let the table view know what needs to be selected:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
UIViewController *destinationController = segue.destinationViewController;
if( [destinationController isKindOfClass:[RepeatViewController class]] )
{
//You can reuse your selectedDays arrays
((RepeatViewController*)destinationController).selectedDays = self.selectedDaysArray;
[(RepeatViewController *)destinationController setReturnBlock:^(NSArray *retDaysArray) // <- make this change
{
// Save your changes
self.selectedDaysArray = [NSMutableArray arrayWithArray: retDaysArray]; // <- make this change
NSLog(#"DATA: %#", self.selectedDaysArray) //<- Add this debug line
}];
}
}
Remove this line from viewDidLoad you don't want to allocate it every time now you just pass it from rootVC
_selectedDays = [[NSMutableArray alloc] init];
And in cellForRowInIndexPath replace this line:
cell.textLabel.text = [completionBlock objectAtIndex:indexPath.row];
with this code:
NSString *day = completionBlock[indexPath.row];
cell.textLabel.text = day;
if ([self.selectedDays containsObject:day])
cell.accessoryType = UITableViewCellAccessoryCheckmark;
else
cell.accessoryType = UITableViewCellAccessoryNone;
And change didSelectRowAtIndexPath: to
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (!self.selectedDays)
self.selectedDays = [[NSMutableArray alloc] init];
if (cell.accessoryType == UITableViewCellAccessoryCheckmark)
{
cell.accessoryType = UITableViewCellAccessoryNone;
//remove data from array
[self.selectedDays removeObject:[completionBlock objectAtIndex:indexPath.row]];
}
else
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
//add data to array
[self.selectedDays addObject:[completionBlock objectAtIndex:indexPath.row]];
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
Hope this help.

How to insert cell into UITableViewController

I'm creating an iPad app. The root UITableview has a right bar button item in the navigation controller. When you tap the button, it shows a pop over controller. The popover is a UITableViewController. When you tap a cell in the popover, how could I pass the data in that cell and insert it into a cell into the root UITableview? I searched the Apple docs and couldn't find what I needed. Can anyone push me in the right direction?
Roottable.h
#interface Roottable : UITableViewController<PopoverDelegate>
Popover.h
#protocol AthleteSelectPopoverDelegate <NSObject>
#required
-(void)selectedObject:(Object *)newObject;
#end
#property (nonatomic, weak) id<PopoverDelegate> delegate;
#property (readwrite, nonatomic) Object *currentObject;
#end
popover.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
_currentObject = [_objectArray objectAtIndex:indexPath.row];
//Notify the delegate if it exists.
if (_delegate != nil) {
[_delegate selectedObject:_currentObject];
}
}
You add data from the selected cell to the main table's data source delegate.
Then that data source should tell the main table that a cell has been inserted at an index path.
I figured it out. Hope I help someone. I'll explain the code first then post it below. Basically, I set the data source of the root table view, "ObjectSelect", as a NSMutableArray called "currentObjectArray". ObjectSelect is also the ObjectSelectPopoverDelegate. Basically, when a cell in the popover is tapped, it adds the object tapped to the "currentObjectArray" and reloads the tableview.
ObjectSelect.h
#import <UIKit/UIKit.h>
#import "ObjectSelectPopover.h"
#interface ObjectSelect : UITableViewController<ObjectSelectPopoverDelegate>
#property (nonatomic, strong) ObjectSelectPopover *objectPicker;
#property (nonatomic, strong) UIPopoverController *objectPickerPopover;
#property (readwrite, nonatomic) Object *currentObject;
#property (nonatomic, strong) NSMutableArray *selectedObjectArray;
#end
ObjectSelect.m
-(void)selectedObject:(Object *)newObject
{
_currentObject = newObject;
if(!_selectedObjectArray){
_selectedObjectArray = [[NSMutableArray alloc] init];
}
if([_selectedObjectArray containsObject:_currentAthlete]){
//lol you don't get added, bub
}
else{
[_selectedObjectArray addObject:_currentObject];
}
[self.tableView reloadData];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
Object *objectTapped = (Object *)[_objectAthleteArray objectAtIndex:indexPath.row];
return cell;
}
ObjectSelectPopover.h
#import <UIKit/UIKit.h>
#import "Object.h"
#protocol ObjectSelectPopoverDelegate <NSObject>
#required
-(void)selectedObject:(Object *)newObject;
#end
#interface ObjectSelectPopover : UITableViewController
#property (nonatomic, weak) id<ObjectSelectPopoverDelegate> delegate;
#property (nonatomic, strong) NSMutableArray *objectArray;
#property (readwrite, nonatomic) Object *currentObject;
#end
ObjectSelectPopover.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
_currentObject = [_objectArray objectAtIndex:indexPath.row];
//Notify the delegate if it exists.
if (_delegate != nil) {
[_delegate selectedObject:_currentObject];
}
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
}
I think you should have a property with a name other than delegate in your popover controller since UITableViewController already has a delegate property for the UITableViewDelegate protocol; maybe masterTable or something.
Then in the selectedObject: implementation in the root UITableView you can do an insert row or add it to the data array and reload the table.
Oops, my bad... #geraldWilliam is right, UITableViewController does not have the delegate property...
What you have seems like it should work... So does the selectedObject: method get called in the delegate? If so, what do you do in that method? If you add the object to the data set (array or dictionary or database) for the root view, insert a row in its tableview (or reload the data), it should work.
Here is some code that works for me. It is not from a popover but from a pushed view but there is no reason that should make a difference:
- (ThingStatus) thingPicker: (ThingPickerTableViewController *) thingPicker didSelectThing: (Thing *) thing {
NSLog( #"Entering %s", __func__ );
// Dismiss the pushed view controller (for you, the popover)
[self.navigationController popViewControllerAnimated: YES];
NSArray *startingList = self.currentCellObjectList;
[self.databaseManager addThing: thing];
NSArray *endingList = self.databaseManager.thingsForTableView;
// Figure out the differences adding made...
DiffResult *changes = [startingList simpleDiffWithArray: endingList];
NSLog( #"%d deletions, %d insertions", changes.deletionCount, changes.insertionCount );
// I only handle insertions in this code... deletions would be similar
__block NSUInteger objIdx = 0;
NSMutableArray *changeableThingList = [startingList mutableCopy];
[changes.insertionIndexes enumerateIndexesUsingBlock: ^( NSUInteger idx, BOOL *stop ) {
NSLog( #" - insert %# at %d", [[changes.insertionObjects objectAtIndex: objIdx] name], idx );
NSIndexPath *indexPath = [NSIndexPath indexPathForRow: idx inSection: 0];
[changeableThingList insertObject: [changes.insertionObjects objectAtIndex: objIdx] atIndex: idx];
self.currentCellObjectList = changeableThingList;
[self.tableView insertRowsAtIndexPaths: [NSArray arrayWithObject: indexPath] withRowAnimation: UITableViewRowAnimationRight];
++objIdx;
}];
[self.databaseManager save];
return [self.databaseManager: thingStatus];
}
Here is some good code to use that may be able to help you.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return self.item.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
//Get the row
Sport *rowSport = self.sports[indexPath.row];
cell.textLabel.text = rowItem.itemName;
cell.detailTextLabel.text = rowItem.section;
return cell;
}
I hope this will help you.

UITableView reloadData doesn't work when change sub object in datasoure.

There are 5 objects in datasoure for example,if the first object is like this:
Obj -> id:1,name:"A"
when I change the object's name to "B";
Obj -> id:1,name:"B"
then [tableView reloadData]
the first cell still display "A",I want to change it to "B".
In the cellForRowAtIndexpath method manage the datasource method properly as it retrives the value from the datasource array and displays it,That is it
I doubt the problem is that the reusability is causing the trouble in your code
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell;
static NSString *cellIdentifier1 = #"surveyCell";
if (tableView== self.surveytableView) {
cell= [tableView dequeueReusableCellWithIdentifier:cellIdentifier1];
if(cell==nil)
{
//alloc the cell
//DO NOT SET THE VALUE HERE
}
//here set the value
return cell;
}
here is the code, what i did was,
created a class called "DataClass" which provides data for your tableview
created objects like you mentioned , i stored it in an array("dataSource")
after that i loaded it to tableview (i assume u are properly wired up tableview datasource and delegate)
I put a button to make change the string in the datasource array.
button's action is connected to method and within that i am reloading the tableview
//class DataClass
#interface DataClass : NSObject
{
#public;
NSString *str;
}
#implementation DataClass
- (id)init
{
[super init];
str = nil;
return self;
}
#end
//viewController.h
#interface ViewController : UIViewController<UITableViewDataSource ,UITableViewDelegate>
{
IBOutlet UITableView *aTableView;
IBOutlet UIButton *aButton;
}
- (IBAction)whenButtonClicked:(id)sender;
#end
//in .m file
#import "ViewController.h"
#import "DataClass.h"
#interface ViewController ()
{
NSMutableArray *DataSource;
}
#end
// ViewController.m
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
aTableView.dataSource = self;
aTableView.delegate = self;
DataSource = [[NSMutableArray alloc]init];
for(int i=0 ; i<5 ; i++)
{
DataClass *data = [[DataClass alloc]init];
data->str=#"hello";
[DataSource addObject:data];
[data release];
}
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *aCell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
if(aCell == nil)
{
aCell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"]autorelease];
}
DataClass *aValue = [DataSource objectAtIndex:indexPath.row];
aCell.textLabel.text = aValue->str;
return aCell;
}
- (IBAction)whenButtonClicked:(id)sender
{
DataClass *aObj = [DataSource objectAtIndex:2];//changing the 3'rd object value as yours in 5th object
aObj->str = #"world";
[aTableView reloadData];
}
#end
//after "changeValue" button pressed the third row displays "world"

How to pass a value from one UIViewController to another

I am making an app where I have to pass a value from a second class to a first class. I have created a delegate method for that in second class.
In second class I have a UITextField, and if enter any text in this textfield it should be passed to a cell in a UITableView in first view.
However, in my case the value is not being passed properly. What have I done wrong?
This is my code:
second.h
#import <UIKit/UIKit.h>
#protocol secondDelegate<NSObject>
#required
- (void)setsecond:(NSString *)inputString;
#end
#interface second : UIViewController {
IBOutlet UITextField *secondtextfield;
id<secondDelegate>stringdelegate;
NSString *favoriteColorString;
}
#property (nonatomic, retain) UITextField *secondtextfield;
#property (nonatomic, assign) id<secondDelegate>stringdelegate;
#property (nonatomic, copy) NSString *favoriteColorString;
#end
second.m
#import "second.h"
#implementation second
#synthesize stringdelegate, secondtextfield, favoriteColorString;
- (void)viewWillDisappear:(BOOL)animated {
[[self stringdelegate] setsecond:secondtextfield.text];
favoriteColorString=secondtextfield.text;
NSLog(#"thuis check:%#", favoriteColorString);
}
- (BOOL)textFieldShouldReturn:(UITextField *)theTextField {
[theTextField resignFirstResponder];
return YES;
}
- (void)viewDidLoad {
[super viewDidLoad];
//[[self stringdelegate] setsecond:secondtextfield.text];
//favoriteColorString = secondtextfield.text;
//NSLog(#"thuis check:%#", favoriteColorString);
}
#end
first.h
#import <UIKit/UIKit.h>
#import "second.h"
#import "TextviewExampleAppDelegate.h"
#interface first : UITableViewController<secondDelegate> {
//TextviewExampleAppDelegate *app;
TextviewExampleAppDelegate *check;
}
first.m
#implementation first
- (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];
}
// Configure the cell...
cell.textLabel.text = #"message";
cell.detailTextLabel.text = check.favoriteColorString;
NSLog(#"this second check:%#", check.favoriteColorString);
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
second *viewtwo = [[second alloc] initWithNibName:#"second" bundle:nil];
//viewtwo.favoriteColorString = indexPath;
viewtwo.stringdelegate = self;
[self.navigationController pushViewController:viewtwo animated:YES];
[viewtwo release];
}
- (void)setsecond:(NSString *)inputString {
if (nil != self.stringdelegate) {
[self.stringdelegate setsecond:inputString];
}
[self.tableView reloadData];
}
#end
remove delegate methods.
import your second class to first one.
in 2nd class import first class and implement id firstClass variable there.
when you pushing 2nd class, set id from (3) to self.
when you'v done and ready to pass it, set firstClass.passedValue = passingValue
pop second class
for example:
//first.h:
#import "second.h"
#class second
//second.h:
#import "first.h"
#class first
...
id firstClass;
//first.m:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
second *viewtwo =[[second alloc]initWithNibName:#"second" bundle:nil];
[self.navigationController pushViewController:viewtwo animated:YES];
viewtwo.firstClass = self;
[viewtwo release];
}
//second.m:
firstClass.passedValue = self.passingValue;
Please refer following rough scratch:
in application delegate .h
Create variable
NSString *varStr;
Assign Property
#propery (nonatomic, retain) NSString *valStr;
In delegate .m
#synthesize varStr;
initialize var
varStr = [NSString strinWithFormat:#"Hi"];
in First class
create delegate var;
delegate class *var = (delegate class*)[[UIApplication sharedApplication] delegate];
set value
var.varStr = [NSString strinWithFormat:#"First"];
get value
NSLog (#"%#",var.varStr);
in Second class
create delegate var;
delegate class *var = (delegate class*)[[UIApplication sharedApplication] delegate];
set value
var.varStr = [NSString strinWithFormat:#"Second"];
get value
NSLog (#"%#",var.varStr);

Resources