Passing data between two table views - iphone

What I am trying to do is .. i want to pass the data between two table views.
In my root view controller I am using an array and then populating it for the RootViewController and in
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
method I am doing this:
if (indexPath.row == 0)
{
self.schedule.title = #"Show1";
NSLog(#"SCHEDULE CONTROLLER TITLE = %#", schedule.title);
NSLog(#"FIRST ROW ");
}
if (indexPath.row == 1) {
self.schedule.title = #"Show2";
NSLog(#"SECOND ROW");
}
if(indexPath.row == 2){
self.schedule.title = #"Show3";
NSLog(#"THIRD ROW");
}
schedule = [[ScheduleViewController alloc] initWithNibName:#"ScheduleViewController" bundle:nil];
[self.navigationController pushViewController:schedule animated:YES];
schedule is another table view so.. what I am doing is I am comparing the titile of schedule to decide the contents of schedule table view, but some how it is not getting the data.
here is ViewDidLoad method of schedule view:
[super viewDidLoad];
if ([self.title isEqualToString:#"Show1"])
{
showSchedule = [[NSArray alloc] initWithObjects:#"SUNDAY",#"MONDAY",#"TUESDAY" , nil];
}
if ([self.title isEqualToString:#"Show2"])
{
showSchedule = [[NSArray alloc] initWithObjects:#"WEDNESDAY",#"THURSDAY",#"FRIDAY" , nil];
}else {
showSchedule = [[NSArray alloc] initWithObjects:#"SATURDAY", nil];
}
[self.tableView reloadData];
The self.title is returning null and therefore it goes into the else loop at the end.
Any ideas what I am doing wrong here.. ?
Thanks for your time in advance

try this.
if ([self.title isEqualToString:#"Show1"])
{
replace this line.
if ([ self.navigationItem.title isEqualToString:#"Show1"])
{
Then try

Adding title before allocing the view...

set your title after alloc the controller
NSString *titleOfTableVC ;
if (indexPath.row == 0)
{
titleOfTableVC = #"Show1";
NSLog(#"SCHEDULE CONTROLLER TITLE = %#", titleOfTableVC );
NSLog(#"FIRST ROW ");
}
if (indexPath.row == 1) {
titleOfTableVC = #"Show2";
NSLog(#"SECOND ROW");
}
if(indexPath.row == 2){
titleOfTableVC = #"Show3";
NSLog(#"THIRD ROW");
}
schedule = [[ScheduleViewController alloc] initWithNibName:#"ScheduleViewController" bundle:nil];
schedule.title = titleOfTableVC ;
[self.navigationController pushViewController:schedule animated:YES];
Hope this will make u understand

Related

reload tableview after call to WCF service

I am calling a WCF service to display data in a UITableViewController.The code in the .m file is:
- (void)viewDidLoad
{
[super viewDidLoad];
[docTable setDataSource:self];
[docTable setDelegate:self];
}
-(void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
EDViPadDocSyncService *service = [[EDViPadDocSyncService alloc]init];
EDVCategory *cat = [EDVCategory alloc];
cat.categoryId = [catId intValue];
[service getDocsByCatId:self action:#selector(getDocsByCatIdHandler:) category:cat];
[docTable reloadData];
}
- (void) getDocsByCatIdHandler: (id)value
{
if([value isKindOfClass:[NSError class]])
{
NSLog(#"%#", value);
return;
}
if([value isKindOfClass:[SoapFault class]])
{
NSLog(#"%#", value);
return;
}
NSMutableArray* result = (NSMutableArray*)value;
NSMutableArray *documentList = [[NSMutableArray alloc] init];
self.myDocList = [[NSMutableArray array] init];
for (int i = 0; i < [result count]; i++)
{
EDVDocument *docObj = [[EDVDocument alloc]init];
docObj = [result objectAtIndex:i];
[documentList addObject:[docObj docName]];
}
self.myDocList = documentList;
[docTable reloadData];
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
int cnt = [self.myDocList count];
NSLog(#"ABC=%#",cnt);
return [self.myDocList count];
//return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
DocumentCell *cell = [tableView dequeueReusableCellWithIdentifier:#"DocumentCell"];
if (cell == nil)
{
cell = [[[DocumentCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"DocumentCell"] autorelease];
}
NSLog(#"cell text=%#",[self.myDocList objectAtIndex:indexPath.row]);
cell.lblDocName.text = [self.myDocList objectAtIndex:indexPath.row];
return cell;
}
I am using storyboard.I have hooked the "docTable",set the datasource and the delegate for "docTable".The problem is,the service is called after the call to "numberOfRowsInSection".So,'return [self.myDocList count]' is 0.I have put [docTable reloadData] in viewWillAppear as well as in the service handler,that is,"getDocsByCatIdHandler".But it isn't getting reloaded,as expected.Is there anything else I can try? EDIT:- This a Master-Detail application.I have used the same code for loading data in the "MasterViewController" UITableViewController and it works.When the user selects a cell in this table,I need to populate data in the second tableview by calling the WCF service.The second tableview isn't displaying data.
Everything looks good which leads me to believe you are not getting the results from the webservice you are expecting.
One small thing first thats not your problem. If result is in fact an array and there is an object in it, you shouldnt need to alloc a new EDVDocument.
EDVDocument *docObj = [result objectAtIndex:i];
Can you log the (id)value parameter to see what we're working with?
NSLog(#"%#", value);
If value is not an array, the cast wont complain, it will just work by not working. However, if it is an array you may be finding trouble with assigning your property (granted I dont know how its declared) to a local array. You can use the following function to create a new array with the elements of your temporary array;
self.myDocList = [[NSArray alloc] initWithArray:documentList];
[docTable reloadData];
I hope this helps.
I was facing the same issue when i have a async webService call. I was using a private Library to call webservice so my control goes to the library and after the response comes a method in Appdelegate is set as handler. So what you need to do is before calling the Webservice save the state of tableview in a shared variable and after you have received response set it back to tableView and then call the reload method. Something like below:
SharedView.tblView = self.tableView;
[webservice Call];
After Response:
self.tableView = SharedView.tblView;
[self.tableView reloadData];
Hope This Helps.

NSZombie in didSelectRowAtIndexPath

I have an interesting problem, and I can't seem to find out why it is happening, might be something small that I am overlooking.
I have a UITableView and in my didselectrowatindex path I navigate to a new view, I then navigate to the next view and pop both views to get back to the first and then the app crashes with the EXC_BAD_ACCESS
So I used instruments and NSZombie and found a malloc in didselectrowatindexpath, but I have no idea why
Here is my code:
if([workflowswithdirectories count] == 0)
{
WorkflowViewController *aWorkFlow = [[WorkflowViewController alloc] init];
MenuObject *obj = [workflownames objectAtIndex:[indexPath row]];
aWorkFlow.heading = obj.name;
aWorkFlow.workId = obj.workflowid;
aWorkFlow.siteId = obj.siteid;
aWorkFlow.item = obj;
[self.navigationController pushViewController:aWorkFlow animated:YES];
}
else if([workflownames count] == 0)
{
WorkflowListViewController *work = [[WorkflowListViewController alloc] init];
work.siteId = self.siteId;
MenuObject *obj = [workflowswithdirectories objectAtIndex:[indexPath row]];
work.menu = obj.next;
work.heading = obj.name;
[self.navigationController pushViewController:work animated:YES];
}
else
{
if([indexPath section] == 0)
{
WorkflowListViewController *work = [[WorkflowListViewController alloc] init];
work.siteId = self.siteId;
MenuObject *obj = [workflowswithdirectories objectAtIndex:[indexPath row]];
work.menu = obj.next;
work.heading = obj.name;
[self.navigationController pushViewController:work animated:YES];
}
else
{
WorkflowViewController *aWorkFlow = [[WorkflowViewController alloc] init];
MenuObject *obj = [workflownames objectAtIndex:[indexPath row]];
aWorkFlow.heading = obj.name;
aWorkFlow.workId = obj.workflowid;
aWorkFlow.siteId = obj.siteid;
aWorkFlow.item = obj;
[self.navigationController pushViewController:aWorkFlow animated:YES]; //Malloc is on this line
}
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
EDIT:
Something I forgot to mention is, in certain cases I push another one of this same class onto the navigationcontroller, but it is only when going to the WorkflowViewController and then to the next viewcontroller and then back twice that the exception is thrown
For memory and efficiency's sake, make all UIViewControllers strong properties (with a backing iVar) to guarantee they stay around long enough for anything useful.

Pass a string from DidSelectRowAtIndexPath to a button-click action

I have this code
NSString *localStringValue;
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
localStringValue = [m_textfield cellForRowAtIndexPath:indexPath].textLabel.text;
localStringValue = [m_textfield cellForRowAtIndexPath:indexPath].detailTextLabel.text;
NSArray* toReload = [NSArray arrayWithObjects: indexPath, self.selectedIndexPath, nil];
self.selectedIndexPath = indexPath;
if ([[tableView cellForRowAtIndexPath:indexPath] accessoryType] == UITableViewCellAccessoryCheckmark){
UploadView *uploadview = (UploadView *)self.view;
if (uploadview != nil)
{
[m_owner uploadString:localStringValue];
//[self dismissModalViewControllerAnimated:YES];
}
[[m_textfield cellForRowAtIndexPath:indexPath] setAccessoryType:UITableViewCellAccessoryNone];
}
else {
[[tableView cellForRowAtIndexPath:indexPath] setAccessoryType:UITableViewCellAccessoryCheckmark];
}
}
in this code i am syncing localStringValue to google-doc when i tap the cell if the check mark is there.localStringValue contains the values in the tableview cell.Every thing works fine at this point.But my need is i want to pass this value to a button click,that means if the user select multiple row i want all the values in the localStringValue and pass this through this code
- (IBAction)doUpload:(id)sender
{
UploadView *uploadview = (UploadView *)self.view;
if (uploadview != nil)
{
[m_owner uploadString:#""];
//[self dismissModalViewControllerAnimated:YES];
}
}
i want to pass localstringvalue in [m_owner uploadString:localstringvalue];
How to do this?
thanks in advance.
you can create a NSMutableArray as class variable and you can add your strings to that on didSelectRowAtIndexPath. Later on on button click you can process the NSMutableArray to fetch strings one by one and sending them to google-doc...etc.
You need to update ur
- (void)doUpload:(NSString*)stringValue
{
UploadView *uploadview = (UploadView *)self.view;
if (uploadview != nil)
{
[m_owner uploadString:localstringvalue];
//[self dismissModalViewControllerAnimated:YES];
}
}
And one more thing
localStringValue = [m_textfield cellForRowAtIndexPath:indexPath].textLabel.text // reassigning the string again so this line does not make any sense.

UITable view: didselectrowatIndexPath for multiple rows

I have a table view(HomeViewController) consisting of items as:
locations >
Reporting >
Setting >
i am able to do this with the help of "didselectrowatIndexPath" for a single row but when i am trying to do so with multiple rows(if else construct), not getting error but still unable to click on any one (locations,reporting or setting).I have imported .h files of all three above.my code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([[menuList objectAtIndex:indexPath.row] isEqual:#"LOCATIONS"])
{
LocationViewController *locationViewController;
locationViewController = [[LocationViewController alloc] initWithNibName:#"LocationViewController" bundle:nil];
locationViewController.menuList = [menuList objectAtIndex:indexPath.row];
[self.navigationController pushViewController:locationViewController animated:YES];
}
else if([[menuList objectAtIndex:indexPath.row] isEqual:#"REPORTING"])
{
Reporting *reporting;
reporting = [[Reporting alloc] initWithNibName:#"Reporting" bundle:nil];
reporting.menuList = [menuList objectAtIndex:indexPath.row];
[self.navigationController pushViewController:reporting animated:YES];
}
//[locationViewController release];
}
Also want to discuss about release statement
help me!
Thanks
isEqual tests the object's equality to another object. If the strings in your menuList array are all in upper case then this is fine. If they're like they are in your example before the code then you're going to have problems. Also, if they're both NSStrings then you should use isEqualToString rather than isEqual. You can test this by doing something like this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *arrayValue = [menuList objectAtIndex:indexPath.row];
NSString *myValue = #"LOCATION";
NSLog(#"array value: '%#' my value: '%#'",arrayValue,myValue);
}
The release is not valid because the object is "out of scope".
An objects scope is the current "visible" code base for that variable. Here are some examples:
- (void)aRandomFunction {
/* here is a variable/object. Its scope is the whole function because it has been
declared directly in the function. All constructs have access to it (within the function) */
NSString *myString = #"My String";
if(YES){
NSLog(#"%#", myString); // myString is visible here because its in scope.
}
}
- (void)anotherRandomFunction {
if(YES){
/* here, because we've declared the variable within the if statement
it's no longer a direct object of the function. Instead its a direct
child of the if statement and is therefore only "visible" within that
if statement */
NSString *myString = #"My String";
NSLog(#"%#", myString); // myString is visible here because its in scope.
}
NSLog(#"%#", myString); // but NOT available here because it is out of scope
}
So in essence, a variable's scope is its direct parent construct and all its parent's children constructs.
So there is two ways to do your example. My favourite is this way:
- (void)aFunctionToPushAViewController {
UIViewController *nextPage = NULL;
if(YES){
nextPage = [[CustomViewController alloc] initWithNibName:nil bundle:nil];
}
else {
nextPage = [[ADifferentViewController alloc] initWithNibName:nil bundle:nil];
}
[self.navigationController pushViewController:nextPage animated:YES];
[nextPage release];
}
or... you can just release it in the if statement...
- (void)aFunctionToPushAViewController {
if(YES){
CustomViewController *nextPage = [[CustomViewController alloc] initWithNibName:nil bundle:nil];
[self.navigationController pushViewController:nextPage animated:YES];
[nextPage release];
}
else {
ADifferentViewController *nextPage = [[ADifferentViewController alloc] initWithNibName:nil bundle:nil];
[self.navigationController pushViewController:nextPage animated:YES];
[nextPage release];
}
}

iPhone - UITableView - lost data if i go back

I have a TabBar, NavBar, SearchBar with ScopeBar on my screen. I can search data via a remote server and list the content. So I have a NSMutableArray listContent and a filteredListContent like in the example of Apple (TableSearch - http://developer.apple.com/iphone/library/samplecode/TableSearch/index.html):
Now I added in
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
these line:
testDetailViewController *testDetailViewController = [[TestDetailViewController alloc] initWithNibName:#"TestDetailView" bundle:[NSBundle mainBundle]];
testDetailViewController.title = testClass.name;
testDetailViewController.myKey = testClass.keyId;
[[self navigationController] pushViewController:testDetailViewController animated:YES];
[testDetailViewController release];
testDetailViewController = nil;
Because of the NavigationBar, there is a "back" button. If I click this button, the TableView is empty, no matches/hits.
What I have to do, so the content will still be there?
Does anyone know?
Thanks a lot in advance & Best Regards.
Source Code:
#implementation SearchViewController
#synthesize listContent, filteredListContent, savedSearchTerm, savedScopeButtonIndex, searchWasActive;
- (void)viewDidLoad {
// restore search settings if they were saved in didReceiveMemoryWarning.
if (self.savedSearchTerm) {
[self.searchDisplayController setActive:self.searchWasActive];
[self.searchDisplayController.searchBar setSelectedScopeButtonIndex:self.savedScopeButtonIndex];
[self.searchDisplayController.searchBar setText:savedSearchTerm];
self.savedSearchTerm = nil;
}
}
- (void)viewDidUnload {
// Save the state of the search UI so that it can be restored if the view is re-created.
self.searchWasActive = [self.searchDisplayController isActive];
self.savedSearchTerm = [self.searchDisplayController.searchBar text];
self.savedScopeButtonIndex = [self.searchDisplayController.searchBar selectedScopeButtonIndex];
self.filteredListContent = nil;
}
- (void)dealloc {
[listContent release];
[filteredListContent release];
[super dealloc];
}
- (void)setData {
self.listContent = [NSMutableArray arrayWithCapacity:3];
[self.listContent addObject:[SearchObjects itemWithType:#"AAA" name:#"Test1"]];
[self.listContent addObject:[SearchObjects itemWithType:#"BBB" name:#"Test2"]];
[self.listContent addObject:[SearchObjects itemWithType:#"BBB" name:#"Test3"]];
// create a filtered list
self.filteredListContent = [NSMutableArray arrayWithCapacity:[self.listContent count]];
[self.tableView reloadData];
self.tableView.scrollEnabled = YES;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
//If the requesting table view is the search display controller's table view, return the count of the filtered list, otherwise return the count of the main list.
if (tableView == self.searchDisplayController.searchResultsTableView) {
return [self.filteredListContent count];
} else {
return [self.listContent count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *kCellID = #"cellID";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellID];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellID] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
/* If the requesting table view is the search display controller's table view, configure the cell using the filtered content, otherwise use the main list. */
SearchObjects *searchObject = nil;
if (tableView == self.searchDisplayController.searchResultsTableView) {
searchObject = [self.filteredListContent objectAtIndex:indexPath.row];
} else {
searchObject = [self.listContent objectAtIndex:indexPath.row];
}
cell.textLabel.text = searchObject.name;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// HERE IS THE SOURCE CODE FOR PUSHING TO THE NEXT VIEW
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
// DO SOME CALCULATIONS… AND THE setData METHOD IS CALLED
}
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope {
/* Update the filtered array based on the search text and scope. */
[self.filteredListContent removeAllObjects]; // First clear the filtered array.
/* Search the main list for whose type matches the scope (if selected) and whose name matches searchText; add items that match to the filtered array. */
for (SearchObjects *searchObject in listContent) {
if ([scope isEqualToString:#"All"] || [searchObject.type isEqualToString:scope]) {
NSComparisonResult result = [searchObject.name compare:searchText options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch) range:NSMakeRange(0, [searchText length])];
if (result == NSOrderedSame) {
[self.filteredListContent addObject:searchObject];
}
}
}
}
- (void)filterContentForScope:(NSString*)scope {
/* Update the filtered array based on the search text and scope. */
[self.filteredListContent removeAllObjects]; // First clear the filtered array.
/* Search the main list for whose type matches the scope (if selected); add items that match to the filtered array. */
for (SearchObjects *searchObject in listContent) {
if ([scope isEqualToString:#"All"] || [searchObject.type isEqualToString:scope]) {
[self.filteredListContent addObject:searchObject];
}
}
}
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
[self filterContentForScope:[[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:[self.searchDisplayController.searchBar selectedScopeButtonIndex]]];
// Return YES to cause the search result table view to be reloaded.
return YES;
}
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption {
[self filterContentForScope:[[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:searchOption]];
// Return YES to cause the search result table view to be reloaded.
return YES;
}
#end
You generally don't have to do anything in this case, the data should remain in place. Is there something which is unloading the data? Do you have a viewWillDisappear function which is unloading your array? Are you doing some of the array setup in viewWillAppear.
Put a log statement at the start of your methods to find out when they are being called, it will give you a clearer picture of what's happening.
It is solved. It was a problem which is not obvious with the given source code.
There was an error in my logic.