I have two UITableViewController classes, MainTableController and SubTableController.
From AppDelegate class I am calling MainTableController class.
At first this class is empty, and there is button named "show list" in this class.
When I click on this button I will go to SubTableController and there I have a list of actions in form of table.
Now if I choose to first cell action then that action name has to come on my first cell of table in MainTableController. But I am not able to print that name in table of MainTableController class.
In SubTableController:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
ActionList * actionListObj = [appDelegate.actionArray objectAtIndex:indexPath.row];
self.chooseActions = actionListObj.actionName;
MainTableController * mainViewController = [[MainTableController alloc] init];
[mainViewController getAction:self.chooseActions];
[self.navigationController dismissModalViewControllerAnimated:YES];
}
In MainTableController:
-(void) viewWillAppear:(BOOL)animated{
[self reloadData];
}
-(void) reloadData{
[self.myTableView reloadData];
}
-(void) getAction: (NSString *) actionChoose{
self.action = actionChoose;
[self reloadData];
}
-(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 = self.action;
return cell;
}
When I debug, in MainTableController I am getting the action in getAction method but in table cell text string is null.
Can anyone please help me regarding this?Where am I going wrong?
You are allocating and initializing a new view controller each time you select a cell in SubTableController.
MainTableController * mainViewController = [[MainTableController alloc] init];
and of course, it isn't the one in place in the navigation stack.
You need to make these two controllers communicate.
I suggest that the sub view controller define a property on the main one, in order to message it when needed.
In SubTableController, add a property and synthesize it :
#property(readwrite, assign) MainViewController *mainViewController;
// and ...
#synthesize mainViewController;
Of course when you push the sub view controller, don't forget to set the property.
// in main view controller
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// alloc/init the sub VC
subVCInstance.mainViewController = self;
[self pushViewController:subVCInstance ......
Now when a row is selected in the sub one, message the main one, without alloc/init a new MainViewController object :
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
ActionList * actionListObj = [appDelegate.actionArray objectAtIndex:indexPath.row];
self.chooseActions = actionListObj.actionName;
//MainTableController * mainViewController = [[MainTableController alloc] init];
[self.mainViewController getAction:self.chooseActions];
[self.navigationController dismissModalViewControllerAnimated:YES];
}
This should work just fine.
In didSelectRowAtIndexPath of the SubTableController class, you are allocating new MainTableController to send the data.
MainTableController * mainViewController = [[MainTableController alloc] init];
[mainViewController getAction:self.chooseActions];
You should not do like that. Because the existing mainview will be different from the newly allocated one. You should use delegate to give back the data. For more info on Protocols and delegates, see here
More example here
Related
I have a tableviewcell in the RegisterViewController, when i click on it, it push to the SelectCityViewController where i can pick a city from a uipickerview. and I have defined a delegate in the SelectCityViewController. But when i implement the delegate method, i got the city back from the pickerview and the selected indexpath from didSelectRowAtIndexPath in RegisterViewController. When i check the log, i get the city, and the selected indexpath. but when i call reloadRowsAtIndexPaths, the cell still got the old titlelabel text. the code:
SelectCityViewController.h
#protocol SelectCityDelegate <NSObject>
- (void)didGetCity:(City *)city;
#end
SelectCityViewController.m
- (void)finished:(UIBarButtonItem *)buttonItem
{
if ([self.delegate respondsToSelector:#selector(didGetCity:)]) {
[self.delegate didGetCity:self.city];
}
NSLog(#"%#", self.city.city);
[self.navigationController popViewControllerAnimated:YES];
}
RegisterViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 2) {
self.selectedIndexPath = indexPath;
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
SelectCityViewController *signUp = [storyBoard instantiateViewControllerWithIdentifier:#"SignVC"];
signUp.delegate = self;
[self.navigationController pushViewController:signUp animated:YES];
}
}
- (void)didGetCity:(City *)city
{
NSLog(#"%#", city.city);
NSLog(#"%#", selectedIndexPath);
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:selectedIndexPath];
cell.textLabel.text = city.city;
[self.tableView reloadRowsAtIndexPaths:#[selectedIndexPath] withRowAnimation:UITableViewRowAnimationFade];
}
I think the problem is in the below code you don't have to set the value here, because when you will reload, it will override the value with what is in the function where you are creating your cells.
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:selectedIndexPath];
cell.textLabel.text = city.city;
Just reload the cell, and put above code in your
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
//Cell intialization and other things
cell.textLabel.text = city.city;
}
didGetCity needs to update the model that backs the table, not the table cell itself. How do you answer numberOfRowsInSection:? With the count of some array?
That array at index selectedIndexPath.row needs to change. cellForRowAtIndexPath: should initialize the cell with that same data. Then your didGetCity method updates the array and reloads. It should not refer to cells.
This is my scenario,
I have ViewController1 and Class1(Service Class).
I am loading tableView in nib by setting delegate and datasource in ViewController1. In viewDidLoad, i am calling a networkCall function in another class(Class1). In Class1, After getting a response it will pass an array of response data to a function in ViewController1 where the data should be populated in tableview.
i have connected datasource and delegate in xib.
Problem:
When i get a response as an array in ViewController1, UITableView becomes nil, i cannot able to use reloadData, but my array contains list of items from server.
Here's my code
ViewController1
- (void)viewDidLoad
{
[super viewDidLoad];
ClassA *class = [[ClassA alloc]init];
[class getResponse];
}
//This method is calling from ClassA using delegate
-(void)responseData:(NSArray*)arrayList
{
//arrayList have response data
[tableView reloadData];//here tableView becomes nil.
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSLog(#"array count %d",array.count);//has number of items(for me, its 3).
return array.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"TableView";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = #"dsds";
return cell;
}
tableView is calling first time.
In ViewController1
in interface, i am setting protocols
<UITableViewDelegate,UITableViewDataSource>
You are creating new instance of ViewController1 instead of using the one that has been loaded.
you can do the following:
for ClassA:
interface:
#interface ClassA : ...
#property (weak) ViewController1 * vcDelegate;
...
#end
implementation:
#implementation ClassA
#synthesize vcDelegate;
...
#end
and instead of
id<ViewController1Protocol>view1 = [[ViewController1 alloc]init];
[view1 responseData:objects];
call
[vcDelegate responseData:objects];
In your ViewController, when creating ClassA you need to set delegate to self:
- (void)viewDidLoad
{
[super viewDidLoad];
ClassA *class = [[ClassA alloc]init];
[class setVcDelegate: self];
[class getResponse];
}
It's not the best implementation, but should give you idea of how to do it.
For example, property should probably be
#property (weak) id<ViewController1Protocol> vcDelegate;
You have to connect your tableView with the table view in the xib.
The red region in the image is not connected with your table view. It is empty.
The best answer on stackoverflow for pushing an array to a tableView cell is "start with something easier". I think we can do better than that...
I believe I have everything in place except I can not find the proper way to address getting the data from the rootView. See Below.
The below code pushes an array to DetailView Controller with three cells in a group with "Get Cell Info Here" in top cell. Can someone explain what I need to do to get the actual data into the top cell? Thanks
RootViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
DetailViewController *selectedCell = [[DetailViewController alloc] initWithStyle:UITableViewStyleGrouped];
[self.navigationController pushViewController:selectedCell animated:YES];
}
DetailViewController.h
#interface DetailViewController : UITableViewController {
NSArray *displayCell;
}
#end
DetailViewController.m
- (void)viewWillAppear:(BOOL)animated
{
//Display the selected cell data
displayCell = [[NSArray alloc] initWithObjects:#"Get Cell Info Here", nil];
//Set the title of the navigation bar
self.navigationItem.title = #"wtf";
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil] ;
// Make cell unselectable
cell.selectionStyle = UITableViewCellSelectionStyleNone;
NSString *cellText = nil;
switch ( indexPath.row ) {
case 0: {
cellText = [displayCell objectAtIndex:indexPath.row];
break ;
}
case 1: {
break ;
}
case 2: {
break ;
default:
break;
}
}
cell.textLabel.text = cellText;
return cell;
}
Add a property to DetailViewController as follows:
#property (nonatomic, retain) NSArray *passedItems;
Then have root view controller pass the items as follows:
selectedCell.passedItems = passedItems; // passedItems is array in rootview controller
Then you can use passedItems in DetailedViewController.
I have UIViewController that contains NSMutableArray , I want to pass this array to UITableViewController and view it on the table .. how can I do that ??
I mean I want to (pass) NSMutableArray or any Variable from UIViewController to UITableViewController not (create) a table
I want to pass newBooksArray to UITableViewController, I wrote in UIViewController:
mytable.gettedBooks = newBooksArray; // gettedBooks is NSMutableArray in UITableViewController
mytable.try = #"Emyyyyy"; // try is a NSString in UITableViewController
and in UITableViewController in DidloadView i wrote
NSLog(#"Try: %#", try); // out is null
NSLog(#"my getted array count: %d", [gettedBooks count]); // out is 0
any help ???
Creating a UITableView and filling with an array
I created the above tutorial specially for this problem.
There are also more methods you can learn about on the developer documents
Firstly, you want to make sure you have the required delegate calls in your #interface:
#interface RootViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
{
NSMutableArray * feed;
UITableView * tableView;
}
You want something similar to the following in your controller:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [feed count];
}
- (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];
}
cell.textLabel.text = [mutableArray objectAtIndex:indexPath.row];
return cell;
}
numberOfRowsInSection makes sure you actually load the required number of cell rows from your NSMutableArray. And cellForRowAtIndexPath actually loads the content from each row of your NSMutableArray into each row of the UITableView.
For passing it to another controller, don't you want something like this?
UITableViewController *viewController = [[UITableViewController alloc] initWithNibName:#"TableXIB" bundle:nil];
[viewController setGettedBooks:newBooksArray];
[self.navigationController pushViewController:viewController animated:YES];
UITableview tutorial and sample code
Hope,this will help you..enjoy
If you are using a Tab Bar controller, and First View controller is table view controller and second is UIView controller. You can Pass data to Table View controller by followoing code segment. You need to declare variable called arrayData (NSMutableArray) in table view controller and set property (Since we need to access this from another class.) From this arrayData, you need to load data in tableView. In View controller class write following code.
NSArray *viewControllers = [self.tabBarController viewControllers];
MyTableViewController *mTable = [viewControllers objectAtIndex:0];
[mTable SetArrayData:arrayFromViewController];
[mTable.tableView reloadData];
If you are using Navigation controller, you can do
NSArray *viewControllers = [self.navigationController viewControllers];
MyTableViewController *mTable = [viewControllers objectAtIndex:0];
[mTable SetArrayData:arrayFromViewController];
[mTable.tableView reloadData];
Optionally you can use delegates.
I am having an issue pushing my view controller from a tableview that was dropped into a viewController, and not a TableViewController.
I have found a thread on here with a solution here
pushViewController is not pushing
The problem is.. I have done his solution and my view still does not push. I have connected my tableview via ctrl+drag to the view controller and set both the dataSource and delegate. In the post i mentioned, they say the solution was to 'create a referencing outlet from the tableview to the view controller.' But I don't exactly know what that means. So help with that would be good as well. I have followed this tutorial and am stuck on step 9 obviously.
The line of code not triggering is
[self.navigationController pushViewController:facility animated:YES];
My code is as follows...
viewTable methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSLog(#"list Size: %#",list);
return [list count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = (UITableViewCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
CustomerListData *customer = [self.list objectAtIndex:indexPath.row];
cell.textLabel.text = customer.facilityName;
// cell.textLabel.text = #"Detail";
return cell;
}
-(void)setValue:(NSMutableArray*)array
{
//NSMutableArray *newArray = [[NSMutableArray alloc] init];
list = array;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
FacilityMissionListViewController *facility = [self.storyboard instantiateViewControllerWithIdentifier:#"facilityMissionList"];
[self.navigationController pushViewController:facility animated:YES];
//UINavigationController* navController = self.navigationController;
}
the very last commented out line is there to check if navigationcontroller was null. It is not.
From what I have gathered the issue here lies in the fact the table view is inside the view controller and its not a "tableviewcontroller." This method apparently works if that is the case, but some other steps must be taken if not.. but I don't know them.
Thanks in advance.
It sounds like your NavigationController is not set up correctly. Could you post the code that sets it up?
Put a :
NSLog(#"%#", self.navigationController);
in your didSelectRowAtIndexPath method and you'll see if the method is being called and if the navigationController is nil. It might be one of this cases.
Otherwise make sure that the FacilityMissionListViewController is not nil either.