I'm pretty new to iPhone application development and I'm doing well so far. But at one point my App doesn't do what it is intend for...
It's a tableview based app and i'm pushing a new controller onto the stack to get some Userinput, but when the controller is popped again the data is somehow gone. Perhaps I've missunderstood something with the pointers??
rootviewcontroller.m:
edit = [fields objectAtIndex: indexPath.row];
listView.element = edit;
[self.navigationController pushViewController: listView animated:YES];
ListView.m:
element.value = [list objectAtIndex: indexPath.row];
[self.navigationController popViewControllerAnimated:YES];
so what am I doing wrong?
Thanks for your help
edit:
the value field is shown in the tableview with the cellForRowAtIndexPath method:
if (indexPath.section == 0) {
UILabel *title = (UILabel*) [cell viewWithTag:1];
UILabel *detail = (UILabel*) [cell viewWithTag:2];
ListElement *l = [fields objectAtIndex: indexPath.row];
title.text = l.name;
detail.text = l.value;
If the data is "gone" means "it's not shown after returning to root view" it can probably be fixed by
- (void) viewWillAppear:(BOOL)animated
{
[self.tableView reloadData];
}
put into RootViewController.
Related
I have done the following code previously on in my app. It is working good with all the iOS other than iOS7. I am changing the navigation title in didSelectRow method but it is not changing my navigation bar title in iOS 7. I create a new controller on run time in didselectrow and giving it a title in this line nextController.title = [dataDict objectForKey: kNestedDataKey_title];
- (void) tableView: (UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath {
NSLogDebug();
NSDictionary *dataDict = [self.data objectAtIndex: indexPath.row];
NSString *classNSString = [dataDict objectForKey: kNestedDataKey_class];
UIViewController *nextController = NULL;
nextController = [[NestedTableViewController alloc] initWithNibName: nil bundle: nil];
[self.navigationController pushViewController: nextController animated: YES];
((NestedTableViewController *) nextController).data = [dataDict objectForKey: kNestedDataKey_data];
nextController.title = [dataDict objectForKey: kNestedDataKey_title];
[nextController release];
}
Note: It is working fine in all the iOS other than iOS 7
I notice a strange behavior in iOS 7, that view loads in memory bit late. so when you are setting title, it is possible label for title is not yet created. SO use this statement before setting tile. this will make sure that your View is created and in memory.
[nextController view];
after this set title
nextController.title = #"Title";
Good luck
Try This code
- (void) tableView: (UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath {
NSLogDebug();
NSDictionary *dataDict = [self.data objectAtIndex: indexPath.row];
NSString *classNSString = [dataDict objectForKey: kNestedDataKey_class];
NestedTableViewController *nextController = NULL;
nextController = [[NestedTableViewController alloc] initWithNibName: nil bundle: nil];
nextController.data = [dataDict objectForKey: kNestedDataKey_data];
nextController.title = [dataDict objectForKey: kNestedDataKey_title];
[self.navigationController pushViewController: nextController animated: YES];
[nextController release];
}
i am new to iphone ,my question is in one view i placed a tableview and display some data on that view,i want to add another view(same view to all cell) when select cell(suppose select first cell view will display and newly add view is used to delet that cell information based on cell index)please tell me how to display view.
In the didSelectRowAtIndexPath method in your TableView class; that is where you deal with the selected row. Here is some code that pushes a webViewController onto the screen :
webViewController = [[WebViewController alloc] init];
WebViewController *wvc = [[WebViewController alloc] init];
NSMutableArray *temp = [eventsDict objectForKey:[datesArray objectAtIndex:[indexPath section]]];
EventObject *tempEvent = [temp objectAtIndex:[indexPath row]];
NSString *eventURL = [tempEvent eventLink];
[wvc setEventWebsite:eventURL];
[self setWebViewController:wvc];
[[self navigationController] pushViewController:webViewController animated:YES];
[wvc release];
[webViewController release];
Basically I have an array of Events, it gets the event you touched using [indexPath row], gets the URL within that Event object, passes it to the webViewController, then it pushes the webViewController onto the screen loading the appropriate link. Hope this helps
If you want to display the same view for all cells - simply create one UIView object and change frame in didSelectRowAtIndexPath delegate method. It will something like this -
At first declare infoView in your .h file UIView *infoView, next steps:
- (void)viewDidLoad {
infoView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
infoView.hidden = YES;
[tableView addSubview:infoView];
[super viewDidLoad]; }
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
CGPoint st = CGPointMake(tableView.frame.size.width/2, cell.frame.size.height*indexPath.row);
infoView.hidden = NO;
infoView.center = st;}
Don't forget to release infoView in dealloc method
How do make the individual cells go to different View Controller. Right now, using the method im using, if i click the first cell, it takes me to a view controller where i have a pic. now if i go back and click the second cell, it takes me to the same view controller. How do i change this so that all the other individual cells go to individual view controller? what do i add or what do i configure?
here my code:
// Customize the appearance of table view cells.
- (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...
NSUInteger row = [indexPath row];
cell.textLabel.text = [breakdownArray objectAtIndex:row];
bookDetailViewController.title = [NSString stringWithFormat:#"%#" , [breakdownArray objectAtIndex:row]];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic may go here. Create and push another view controller.
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:#"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
*/
NSInteger row = [indexPath row];
if (self.bookDetailViewController == nil); {
BookDetailViewController *aBookDetail = [[BookDetailViewController alloc] initWithNibName:#"BookDetailView" bundle:nil];
self.bookDetailViewController = aBookDetail;
[aBookDetail release];
}
bookDetailViewController.title = [NSString stringWithFormat:#"%#" , [breakdownArray objectAtIndex:row]];
Books2010AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
[delegate.breakdownNavController pushViewController:bookDetailViewController animated:YES];
}
One fairly easy way is in your tableView:didSelectRowAtIndexPath: method. You can check the index path parameter and execute different code paths. Something like:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath )indexPath {
switch(indexPath.row) {
case 1:
[self.navigationController pushViewController:someViewController animated:YES];
break;
case 2:
[self.navigationController pushViewController:someOtherViewController animated:YES];
break;
}
}
Like most design choices, this is just an example of one possible approach. That's the best I can do in this general case.
I would create a new view controller each time instead of using the same one and just changing its properties, more like the example that you have commented out in tableView:didSelectRowAtIndexPath:. This will only work if you don't access your controller from anywhere other than these methods.
First: Remove bookDetailViewController.title = [NSString stringWithFormat:#"%#" , [breakdownArray objectAtIndex:row]]; from your tableView:cellForRowAtIndexPath: method (you should do this anyway, since it is just taking more processor time)
Second: Remove the bookDetailController property from your class. You won't need it anymore.
Third: Implement tableView:didSelectRowAtIndexPath: as follows:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)path {
BookDetailViewController *bookDetailViewController = [[BookDetailViewController alloc] initWithNibName:#"BookDetailView" bundle:nil];
NSInteger row = path.row;
bookDetailViewController.title = [NSString stringWithFormat:#"%#" , [breakdownArray objectAtIndex:row]];
//Any other setup on view controller
Books2010AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
[delegate.breakdownNavController pushViewController:bookDetailViewController animated:YES];
[bookDetailViewController release];
}
After retrieving search results from a UISearchBar, the results appear in my tableview correctly, but the view is 'greyed out' (see image below)..Any help on this is appreciated, I can't find a solution the Apple documentation.
This is my code that is fired upon hitting the Search button:
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
isSearchOn = YES;
canSelectRow = YES;
self.tableView.scrollEnabled = YES;
CityLookup *cityLookup = [[CityLookup alloc] findCity:searchBar.text];
if ([cityLookup.citiesList count] > 0) {
tableCities = cityLookup.citiesList;
}
[cityLookup release];
isSearchOn = NO;
self.searchBar.text=#"";
[self.searchBar setShowsCancelButton:NO animated:YES];
[self.searchBar resignFirstResponder];
[self.navigationController setNavigationBarHidden:NO animated:YES];
[self.tableView reloadData];
}
And this is how the table view is being refreshed:
-(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;
}
NSString *cellValue = [tableCities objectAtIndex:indexPath.row];
cell.textLabel.text = cellValue;
return cell;
}
If you are using the full package with a UISearchDisplayController the following line should remove the search interface:
[self.searchDisplayController setActive:NO animated:YES];
If you are not using UISearchDisplayController I would recommend checking it out and see if it doesn't suit your needs.
Remark: There is nothing in your posted code that would remove whatever view you have used to grey out the table view. So if you are not using UISearchDisplayController look in the code that displays the search interface to see what you need to do to remove it.
Your not hiding your search bar when hitting search, try:
[self.navigationController setNavigationBarHidden:YES animated:YES];
My problem is that the cell.textLabel does not display the new data following a reload. I can see the cellForRowAtIndexPath being called so I know the reloadData call goes thru. If I log the rowString I see the correct value so the string I set label text to is correct. What am I doing wrong?
I have following code :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSUInteger row = [indexPath row];
static NSString *RowListCellIdentifier = #"RowListCellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:RowListCellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:RowListCellIdentifier]autorelease];
}
NSMutableString *rowString = [[NSMutableString alloc] init];
[rowString appendString:[[[rows objectAtIndex:row] firstNumber]stringValue]];
[rowString appendString:#" : "];
[rowString appendString:[[[rows objectAtIndex:row] secondNumber]stringValue]];
[rowString appendString:#" : "];
[[cell textLabel] setText:rowString];
[rowString release];
return cell;
}
- (void)viewWillAppear:(BOOL)animated {
[self.tableView reloadData];
[super viewWillAppear:animated];
}
try
cell.textLabel.text = $VALUE;
if it doesnt help, are you sure that you have set the tableView.delegate AND the tableView.dataSource?
Try:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.tableView reloadData];
}
What you have now is an unusual construction and might be preventing updates to the UI. In methods that set up a view, you want to call the superclass method before the subclass operations. You reverse the order in methods that tears down a view. You usually don't have to call the viewWillAppear of the super unless you have a custom superclass.
I bet your cell.textLabel is somehow being reset to nil. In my experience I find it easiest to treat the cellForRowAtIndexPath: method as if it's always creating a new cell. Even when it's reusing a cell I want to be ready for everything.
The Header file for cell.textLabel state that the default value is nil. This means that you want to assign a label to the textLabel before you go about changing it's text property.
To do that, replace:
[[cell textLabel] setText:rowString];
with:
UILabel *label = [[UILabel alloc] init];//or initWithFrame:
label.text = rowString;
/* Insert your own customization here */
label.font = [UIFont boldSystemFontOfSize:13.0];
label.backgroundColor = [UIColor clearColor];
label.adjustsFontSizeToFitWidth = YES;
cell.textLabel = label;
[label release];