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.
Related
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
i have search thousand in GG to find solution update data to UITableViewCell but all show me the solution is
UITableViewCell *cell=(UITableViewCell*)[self.tableView cellForRowAtIndexPath:indexPath];
but the cell is nil for all cells that are visible. I have use NSNotification to send data from one method to ViewController.m , and the Reiever method i want update data to cell by indexPath. but all cell is nil and cannt not update that.
here my code
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
#property(nonatomic, strong) IBOutlet UITableView *tableView;
#end
ViewController.m
#implementation ViewController
{
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(theReciever:) name:#"theSender" object:nil];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [recipes count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableCell";
UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
NSLog(#"cell nil");
}
NSString *idgame=#"Gamexyz";
cell.textLabel.text = idgame;
cell.tag=indexPath.row;
return cell;
}
-(void)theReciever:(NSNotification*)notif{
if([notif.object isKindOfClass:[packeData class]]){
packeData *data=[notif object];
NSString *key=data.key;
NSInteger *index=[key integerValue];
NSIndexPath *indexPath=[NSIndexPath indexPathWithIndex:index];
UITableViewCell *cell=(UITableViewCell*)[self.tableView cellForRowAtIndexPath:indexPath];
//UITableViewCell *cell=(UITableViewCell*)[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:7 inSection:0]];
if(cell==nil)
{
NSLog(#"cell NULL");
}else{
cell.textLabel.text=data.process;
}
}else{
NSLog(#"ERR: object not recognised");
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
any one can help me or solution example for update data in UITableViewCell by indexPath
NOTE: below is just an example u can do it in new project
One thing u need to change the data model packeData, lets say it contains key as NSIntager which holdes the index of the cell and process is NSString which holds the progress as string value for example
in packeData.h
#import <Foundation/Foundation.h>
#interface packeData : NSObject
#property (nonatomic, assign) NSInteger key; //holds index
#property (nonatomic, strong) NSString *process; //holds the progress info
#end
and in packeData.m
#import "packeData.h"
#implementation packeData
- (id)init //simply initialise it
{
self = [super init];
if(self)
{
}
return self;
}
#end
and in view controller where u are tableview,
in ViewController.h
#import <UIKit/UIKit.h>
#import "packeData.h"
#interface ViewController : UIViewController <UI TableViewDataSource,UITableViewDelegate>
#property (weak, nonatomic) IBOutlet UITableView *aTableView;
#property (strong,nonatomic) NSMutableArray *recipes; //array acts as datasource
#end
in in ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(theReciever:) name:#"theSender" object:nil];
_recipes = [[NSMutableArray alloc]init]; //initilise your datasource
for(int j = 0 ;j< 20;j++)
{
// for my example i took some values
//initially put some initial values
packeData *data = [[packeData alloc] init];
data.key = j;
data.process = [NSString stringWithFormat:#"game_name_%d",j];
[_recipes addObject:data];
}
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[NSTimer scheduledTimerWithTimeInterval:0.8 target:self selector:#selector(PostNotification) userInfo:nil repeats:YES]; //just for testing
}
- (void)PostNotification
{
//i am simply posting the notification with some random values
packeData *data = [[packeData alloc]init];
data.key = arc4random()%15;
data.process = [NSString stringWithFormat:#"%ld",( data.key + 20)];
[[NSNotificationCenter defaultCenter] postNotificationName:#"theSender" object:data];
}
- (void)theReciever:(NSNotification *)notif
{
if([notif.object isKindOfClass:[packeData class]]){
packeData *data=[notif object];
NSInteger key=data.key;
NSInteger index= key;
//modify the datasource
packeData *recipes_data = [_recipes objectAtIndex:index]; //get the pocket present in array
recipes_data.process = data.process; //modify the recipes data
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:0];
UITableViewCell *cell=(UITableViewCell*)[self.aTableView cellForRowAtIndexPath:indexPath];
if(cell==nil)
{
NSLog(#"cell NULL");
}else
{
[self.aTableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
// cell.textLabel.text=data.process; no need u already mofied the content in the datasource this will call the "cellForRowAtIndexPath" method and displays the process in place of game name
}
}else{
NSLog(#"ERR: object not recognised");
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [_recipes count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableCell";
UITableViewCell* cell = [self.aTableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
NSLog(#"cell nil");
}
packeData *idgame= [_recipes objectAtIndex:indexPath.row];
cell.textLabel.text = idgame.process; //initially contains game name
cell.tag=indexPath.row;
return cell;
}
#end
EDIT
replace the below methods
- (void)PostNotification
{
//i am simply posting the notification with some random values
packeData *data = [[packeData alloc]init];
data.key = arc4random()%15; //15 change the number of rows
data.process = [NSString stringWithFormat:#"%ld",( data.key + arc4random() % 100)];
[[NSNotificationCenter defaultCenter] postNotificationName:#"theSender" object:data];
}
- (void)theReciever:(NSNotification *)notif
{
if([notif.object isKindOfClass:[packeData class]]){
packeData *data=[notif object];
NSInteger key=data.key;
NSInteger index= key;
//modify the datasource
packeData *recipes_data = [_recipes objectAtIndex:index]; //get the pocket present in array
recipes_data.process = data.process; //modify the recipes data
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:0];
UITableViewCell *cell=(UITableViewCell*)[self.aTableView cellForRowAtIndexPath:indexPath];
if(cell==nil)
{
NSLog(#"cell NULL");
[self.aTableView reloadData]; //if cell is not visible then reload the whole table
}else
{
[self.aTableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
// cell.textLabel.text=data.process; no need u already mofied the content in the datasource this will call the "cellForRowAtIndexPath" method and displays the process in place of game name
}
}else{
NSLog(#"ERR: object not recognised");
}
}
Edit 2
as for testing just change the below method and as soon as simulator launches the app scroll to down so that only top 5 rows only updates, wait for 5 to 10 seconds and scroll to top and u will see all the calls are updates with same process 5
//scroll down as soon as launches the app and wait for 5 to 10 seconds then scroll to top u will see top 5 cells are updates with progress 5
- (void)PostNotification
{
packeData *data = [[packeData alloc]init];
data.key = arc4random()%5; //only top 5 cells are modify other wont modify
data.process = [NSString stringWithFormat:#"%ld",5];//updates with some same progress lates give it as 5 //( data.key + arc4random() % 100)];
[[NSNotificationCenter defaultCenter] postNotificationName:#"theSender" object:data];
}
form the above test u will see the top 5 cells are updates even when they are not visible
You can't set the value of any of your cell's controller apart from cellForRowAtIndexPath you have to populate the UITableViewCell data with an array, then when you want to update the data in your cell, update your array according to data, then update the single cell of your UITableView like this.
[tableView beginUpdates];
[tableView reloadRowsAtIndexPaths:#[indexPathOfYourCell] withRowAnimation:UITableViewRowAnimationNone];
[tableView endUpdates];
Just specify your index path of your row and reload...
NSIndexPath* path = [NSIndexPath indexPathForRow:3 inSection:0];
NSArray* rowsToReload = [NSArray arrayWithObjects:path, nil];
[tableView reloadRowsAtIndexPaths:rowsToReload withRowAnimation:UITableViewRowAnimationNone];
I'm just going to be crazy. I want to display some attributes from an object in a TableViewController.
To resume :
I've got a first screen with a list of different Aircraft. Each Aircraft is different and get 2 attributes (a name and an identification number). When i click on an aircraft i want to display its informations in a new view controller (here a TableViewController).
The only thing i get is an empty string... I don't understand how to do this.
Here my code for AircraftViewController.h (the list of different aircraft)
#import <UIKit/UIKit.h>
#import "AircraftInfoViewController.h"
#interface AircraftViewController : UITableViewController <AircraftInfoViewControllerDelegate>
#property (nonatomic, strong) NSMutableArray *aircraft;
#end
Here my code for AircraftViewController.m
#import "AircraftViewController.h"
#import "Aircraft.h"
#interface AircraftViewController ()
#end
#implementation AircraftViewController
{
NSString *_info;
}
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (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 [self.aircraft count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
AircraftCell *cell = (AircraftCell *)[tableView dequeueReusableCellWithIdentifier:#"AircraftCell"];
Aircraft *aircraft = (self.aircraft)[indexPath.row];
cell.immatLabel.text = aircraft.immat;
return cell;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"PickInfo"]) {
AircraftInfoViewController *aircraftInfoViewController = segue.destinationViewController;
aircraftInfoViewController.delegate = self;
aircraftInfoViewController.info = _info;
}
}
- (void)aircraftInfoViewController:(AircraftInfoViewController *)controller didSelectInfo:(NSString *)info
{
_info = info;
Aircraft *aircraft = [[Aircraft alloc] init];
// Here is my problem !
NSLog(#"String is %#", aircraft.name);
[self.navigationController popViewControllerAnimated:YES];
}
#end
Here my Aircraft Object
#import <Foundation/Foundation.h>
#interface Aircraft : NSObject
#property (nonatomic, copy) NSString *name;
#property (nonatomic, copy) NSString *immat;
#end
Here my AircraftInfoViewController.h (where i display info)
#class AircraftInfoViewController;
#protocol AircraftInfoViewControllerDelegate <NSObject>
- (void)aircraftInfoViewController:(AircraftInfoViewController *)controller didSelectInfo:(NSString *)info;
#end
#interface AircraftInfoViewController : UITableViewController
#property (nonatomic, weak) id <AircraftInfoViewControllerDelegate> delegate;
#property (nonatomic, strong) NSString *info;
#end
Here my AircraftInfoViewController.m
#import "AircraftInfoViewController.h"
#interface AircraftInfoViewController ()
#end
#implementation AircraftInfoViewController
{
NSArray *_infos;
NSUInteger _selectedIndex;
}
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
_infos = #[#"TEST"];
_selectedIndex = [_infos indexOfObject:self.info];
}
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [_infos count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"AircraftCell"];
cell.textLabel.text = _infos[indexPath.row];
if (indexPath.row == _selectedIndex) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if (_selectedIndex != NSNotFound) {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:
[NSIndexPath indexPathForRow:_selectedIndex inSection:0]];
cell.accessoryType = UITableViewCellAccessoryNone;
}
_selectedIndex = indexPath.row;
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
NSString *info = _infos[indexPath.row];
[self.delegate aircraftInfoViewController:self didSelectInfo:info];
}
#end
Thx for helping...
I don't exactly get your problem, but in your code you are:
//1. creating a new aircraft
Aircraft *aircraft = [[Aircraft alloc] init];
//2. this aircraft object is new and dose not have a name yet as you never assigned a name to it.
//3. this is why your log shows an empty string
NSLog(#"String is %#", aircraft.name);
Looks like you need to print the info:
NSLog(#"String is %#", _info);
But it will be helpful to help you if you could explain what you want to get better.
On my xcode project I have a view with a tableview. I also have a "special" string that contains the objects to populate the array that populates the tableview.
Example:
NSString *myValues=[[NSString alloc]init];
myValues = #"aaa$bbb$ccc?111$222$333?";
as you can see the characters $ and ? separate the objects.
When I call the view I populate the array by the string but the tableview doesn't work. Here some code:
File.H:
#import <UIKit/UIKit.h>
#interface EquipaggioVC : UIViewController <UITableViewDelegate, UITableViewDataSource>{
UITableView *tableViewEquipaggio;
UITableViewCell *nibLoadedCell;
NSMutableArray *arrayEquipaggio;
NSString *stringaDati;
}
#property (nonatomic, retain) IBOutlet UITableView *tableViewEquipaggio;
#property (nonatomic, retain) IBOutlet UITableViewCell *nibLoadedCell;
#property (nonatomic, retain) NSMutableArray *arrayEquipaggio;
#property (nonatomic, retain) NSString *stringaDati;
#end
File.M:
#import "EquipaggioVC.h"
#import "AppDelegate.h"
#import "ClassEquipaggio.h"
#interface EquipaggioVC ()
#end
#implementation EquipaggioVC
#synthesize tableViewEquipaggio;
#synthesize nibLoadedCell;
#synthesize arrayEquipaggio;
#synthesize stringaDati;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
-(NSString *)uuid
{
//to create an ID
CFUUIDRef uuidRef = CFUUIDCreate(NULL);
CFStringRef uuidStringRef = CFUUIDCreateString(NULL, uuidRef);
CFRelease(uuidRef);
return [(NSString *)uuidStringRef autorelease];
}
-(void)loadTestData:(NSString*)stringaDatiArray{
//populate the array by the string.
if(stringaDatiArray!=nil){
NSArray *elenco=[stringaDatiArray componentsSeparatedByString:#"?"];
for (int i=0; i<([elenco count]-1) ; i++) {
NSString *dettagliEquipaggio=[[NSString alloc]init];
dettagliEquipaggio=[elenco objectAtIndex:i];
NSArray *dettagli=[dettagliEquipaggio componentsSeparatedByString:#"$"];
ClassEquipaggio *aEquipaggio=[[ClassEquipaggio alloc]init];
aEquipaggio.idMembro=[dettagli objectAtIndex:0];
aEquipaggio.sessoMembro=[dettagli objectAtIndex:1];
aEquipaggio.dataNascitaMembro=[dettagli objectAtIndex:2];
[arrayEquipaggio addObject:aEquipaggio];
[aEquipaggio release];
}
}
}
- (UITableViewCell *)tableView:(UITableView *)tableEquipaggioView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
static NSString *sLoadNibNamed;
UITableViewCell *cell;
ClassEquipaggio *aEquipaggio=[arrayEquipaggio objectAtIndex:indexPath.row];
cell = [tableEquipaggioView dequeueReusableCellWithIdentifier:CellIdentifier];
sLoadNibNamed=#"EquipaggioCell";
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:sLoadNibNamed owner:self options:NULL];
cell = [self typeNibLoadCell:aEquipaggio.idMembro];
}
// Configure the cell
UILabel *tipoSessoLabel = (UILabel*) [cell viewWithTag:1];
tipoSessoLabel.text = aEquipaggio.sessoMembro;
UILabel *dataNascitaLabel=(UILabel*)[cell viewWithTag:2];
dataNascitaLabel.text=aEquipaggio.dataNascitaMembro;
return cell;
}
-(NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section{
return [arrayEquipaggio count];
}
-(UITableViewCell *)typeNibLoadCell:(NSString *)named{
return nibLoadedCell;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the specified item to be editable.
return NO;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (void)viewDidLoad
{
[super viewDidLoad];
arrayEquipaggio=[[NSMutableArray alloc]init];
stringaDati=[[NSString alloc]init];
tableViewEquipaggio=[[UITableView alloc]init];
}
-(void)viewDidAppear:(BOOL)animated{
AppDelegate *appDelegate=(AppDelegate*)[[UIApplication sharedApplication]delegate];
UIBarButtonItem * btnIndietroa = [[[UIBarButtonItem alloc] initWithTitle:#"Indietro"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(editNavButtonPressed)]autorelease];
[self.navigationItem setLeftBarButtonItem:btnIndietroa];
stringaDati = [[NSUserDefaults standardUserDefaults] objectForKey:#"stringaDati"];
if(stringaDati!=nil){
[arrayEquipaggio removeAllObjects];
[self loadTestData:stringaDati];
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)dealloc{
[super dealloc];
}
#end
On nib file the tableview has the connection with the delegate and datasource, as the IBoutlet is connected with it.
Thanks for your support.
EDIT: [arrayEquipaggio count] return 0.
By the looks of your question your problem is that the method cellForRowAtIndexPath is not being called and as you said the [arrayEquipaggio count] return 0.
Since you are using that array at the method numberOfRowsInSection with a return value of 0 is normal that your table is not calling the method cellForRowAtIndexPath. Since you are telling to your table that there are no rows.
If you want your table to be populated then check that your array return a value greater than 0.
In a nutshell It has no data to populate your table, that why it doesnt work.
Check that in your viewDidAppear:(BOOL)animated that your are pulling anything to stringaDati.
NSLog(#"info: %#",stringaDati);
Hi I'm trying to reload my table view based off of two different arrays. Which array should be loaded is determined by a segment control in the navigation bar. Currently it only will load the first array and nothing happens when the segment control is pressed. Below is my code any help as to why this isn't working is greatly appreciated. I've also checked that my IBAction segmenter is connected in the nib.
MessageViewController.h
#import <UIKit/UIKit.h>
#interface MessageViewController : UIViewController<UITableViewDelegate> {
IBOutlet UISegmentedControl *segmentControl;
IBOutlet UINavigationBar *navBar;
IBOutlet UITableView *tableView;
}
#property (retain, nonatomic) IBOutlet UISegmentedControl *segmentControl;
#property (retain, nonatomic) IBOutlet UITableView *tableView;
#property (nonatomic, retain) NSMutableArray *inbox;
#property (nonatomic, retain) NSMutableArray *sent;
#end
MessageViewController.m
#import "MessageViewController.h"
#interface MessageViewController () <UITableViewDelegate>
#end
#implementation MessageViewController
#synthesize segmentControl;
#synthesize inbox;
#synthesize sent;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.tabBarItem.title = NSLocalizedString(#"Messages", #"Messages");
self.tabBarItem.image = [UIImage imageNamed:#"mail_2_icon&32"];
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.delegate = self;
self.inbox = [NSMutableArray arrayWithObjects:#"testing", #"test", #"another", nil];
self.sent = [NSMutableArray arrayWithObjects:#"test", #"another", #"testing", nil];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#pragma mark Table view methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if(segmentControl.selectedSegmentIndex == 0){
return [inbox count];
}else if(segmentControl.selectedSegmentIndex == 1){
return [sent count];
}else{
return [inbox count];
}
}
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
if(segmentControl.selectedSegmentIndex == 0){
NSString *cellValue = [inbox objectAtIndex:indexPath.row];
cell.textLabel.text = cellValue;
}else if(segmentControl.selectedSegmentIndex == 1){
NSString *cellValue = [sent objectAtIndex:indexPath.row];
cell.textLabel.text = cellValue;
}else{
NSString *cellValue = [inbox objectAtIndex:indexPath.row];
cell.textLabel.text = cellValue;
}
return cell;
}
-(IBAction)segmenter{
[tableView reloadData];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
}
- (void)dealloc {
[inbox release];
[sent release];
[segmentControl release];
[segmentControl release];
[super dealloc];
}
- (void)viewDidUnload {
[self setSegmentControl:nil];
[segmentControl release];
segmentControl = nil;
[super viewDidUnload];
}
#end
Not sure why it wasn't working in the end all I did was delete the three classes and redo everything with the code above something must have just got borked along the way but it's working now and I'm a happy camper. Didn't need the delegate stuff either since that's all done in the nib so my original code worked fine.
set the delegate and datasource methods and take breakpoint to check the data . your code is right .
tableview.delegate=self;
tableView.datasource=self;
The only problem I see is that you're using a view controller with a table view in it, but you're not setting up the delegate for it in your viewDidLoad, and you're not implementing the delegate for your view controller.
#interface MessageViewController () <UITableViewDelegate, UITableViewDataSource>
#end
In viewDidLoad:
self.tableView.delegate = self;
self.tableView.dataSource = self;
Also make sure you have everything hooked up properly in IB, both your segmented control and your table view.
EDIT: I made my own test as per what you're trying to do, Here's my own implementation file