Right now I have an indexed UITableView that goes to a detail view but i want it to go to another UITableView then a detail view.
my code like this:
`
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
displyAnnController *anController = [[displyAnnController alloc] initWithNibName:#"AnnView" bundle:[NSBundle mainBundle]];
DetailViewController *dvController = [[DetailViewController alloc] initWithStyle:UITableViewStyleGrouped];
switch (indexPath.row) {
case 0:
[self.navigationController pushViewController:anController animated:YES];
[anController release];
anController = nil;
break;
case 1:
[self.navigationController pushViewController:dvController animated:YES];
[dvController release];
dvController = nil;
break;
default:
break;
}`
and when I press the cell with index 0 in the simulator, the program is crash!
what's the problem? pleas help me ..
No, I didn't override the -initWithNibName, I just use it as the same way here,but to push to ControlView NOT TableView.Also,no errors in debug console.
and I have tried to release the controllers after the switch block, but the program still crash :(
anyway, it's work when I write:
displyAnnController *anController = [[displyAnnController alloc] initWithStyle:UITableViewStyleGrouped]];
instead of :
displyAnnController *anController = [[displyAnnController alloc] initWithNibName:#"AnnView" bundle:[NSBundle mainBundle]]
Temporarily, I accept this just to complete my work! but I hope to find any help example because no need to be as group.
thanks all for help and recommendations.
View the debug console (Cmd-Shift-R) and see what the error is.
Are you overriding the -initWithNibName message on displyAnnController? Or the -viewDidLoad message?
You also have a memory leak. You always +alloc both controllers, but only -release one of them. Don't +alloc your controller unless you are going to actually use it.
I think your application is crashing because first you have released the view and then you are making it nil.If it is released once then it is not getting the reference to make it nil.Try it once.It may work.
Related
I have some apps designed for iOS 6 and today I went to upgrade them to iOS 7.
They are a simple table view lists and when a record is selected it displays details about that row on another screen. This worked flawlessly in iOS 6. With iOS 7 when I select a row it shows a blank data page on the first selection. If I then go back to the list and reselect the item it then displays the proper data.. After this first blank display it will work fine for any other records..
I am racking my brain and can not for the life of me figure out why this is happening.
Any ideas?
CODE:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
Statutes *statute = (Statutes *)[self.statutes objectAtIndex:indexPath.row];
if(self.detailView == nil) {
DetailViewController *viewController = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:nil];
self.detailView = viewController;
[viewController release];
}
[self.navigationController pushViewController:self.detailView animated:YES];
self.detailView.title = [statute myStatute];
[self.detailView.statuteFullText setText:[statute myDescription]];
[self.detailView.statuteTitle setText:[statute myTitle]];
[self.detailView.favoritesID setText:[statute myPriority]];
[self.detailView.recordID setText:[statute myRecord]];
if ([#"1" isEqualToString:[statute myPriority]]) {
[self.detailView.favoriteControl setTitle:#"Remove from favorites"];
} else {
[self.detailView.favoriteControl setTitle:#"Add to favorites"];
}
}
Also, the part that changes the button title Add to Favorites etc, does not change on the first item selection, it simply shows "Item".
Thanks.
UPDATE:
So I narrowed it down to this piece of code:
if(self.detailView == nil) {
DetailViewController *viewController = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:nil];
self.detailView = viewController;
[viewController release];
}
If I remove the if clause then it happens on every selection. If I comment out the whole code I cant make any selections. So I imaging I have to find another way to initialize my view controller. Any ideas? Why did this work in iOS 6 then?
NEW ANSWER: (9/25/13)
I was bothered by the backwards hack that I had to do to get this to work, plus when I called the detailView from other screens I ran into a similar problem that was not fixed by this hack so I found another easier fix..
All I had to do was surround the commands that were used to set the values on the view in question within a asynchronous tag and viola! Everything worked..
Here is my solution:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
Statutes *statute = (Statutes *)[self.statutes objectAtIndex:indexPath.row];
if(self.detailView == nil) {
DetailViewController *viewController = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:nil];
self.detailView = viewController;
[viewController release];
}
[self.navigationController pushViewController:self.detailView animated:YES];
dispatch_async(dispatch_get_main_queue(), ^{
self.detailView.title = [statute myStatute];
[self.detailView.statuteFullText setText:[statute myDescription]];
[self.detailView.statuteTitle setText:[statute myTitle]];
[self.detailView.favoritesID setText:[statute myPriority]];
[self.detailView.recordID setText:[statute myRecord]];
if ([#"1" isEqualToString:[statute myPriority]]) {
[self.detailView.favoriteControl setTitle:#"Remove from favorites"];
} else {
[self.detailView.favoriteControl setTitle:#"Add to favorites"];
}
});
}
So now as u can see the
dispatch_async(dispatch_get_main_queue(), ^{
is around the items to be set on the view. I got rid of all of the extra crap in the -ViewDidLoad section...
perfect.
OLD ANSWER: (9/24/13)
Well, I got it to work. It is a total backwards hack but I'm results driven so I don't care. It does kind of upset me that this functionality has changed and needed this hack but whatever.. I hope this helps others who I am sure may be running into this.
I left the above code alone and in the
- (void)viewDidLoad
section I added the following code:
DetailViewController *viewController = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:nil];
self.detailView = viewController;
[viewController release];
[self.navigationController pushViewController:self.detailView animated:YES];
dispatch_async(dispatch_get_main_queue(), ^{
[self.navigationController popToRootViewControllerAnimated:NO];
});
What this does is instantiates the DetailViewController, displays it, then pops it. When the app loads it appears to be at the main screen, as expected, and when making a selection it now works on the first time because technically it is NOT the fist time...
-LK
I have a project where I want to open a UITableViewController after a UITableViewController via a UINavigationController. The thing is, it works the first time when it gets called by this function:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
SDMetadataEntity *entity = [self.optionItems objectAtIndex:indexPath.row];
SudzcDetailViewController *detailViewController = [[SudzcDetailViewController alloc] init];
detailViewController.refName = entity.Name;
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
[entity release];
}
But when I press the back button on the navigation bar, and press the same item again, it crashes! It doesn't crash when I press a different item in the first UITableViewController. I would really like to learn from what I am doing wrong!
You should not
[entity release];
because when you do
[self.optionItems objectAtIndex:indexPath.row];
you just fetching a pointer to it, not init/copy/retaining it.
You shouldn't be releasing entity.
You got that object from an array, you don't own it, so when you release it you may be causing it to be deallocated prematurely.
I have a modal view that is a Navigation Controller. When one of the rows in its UITableView gets tapped, the correct View Controller for that row should be initialized and pushed onto the Navigation Controller's stack (so that the screen now shows that View Controller). But it's not working. I've been trying to debug it for a while, and it appears that the Navigation Controller's retain count is 0 at the time pushViewController is called. I assume that means it has been deallocated, and that this is the root of the problem. But I can't figure out why.
In the following code, AddSportDelegate.m presents the modal view that contains the necessary Navigation Controller (_addItemNavController) initialized with the necessary AddItemTableViewController. Tapping on one of the rows of the Table View managed by AddItemViewController calls the showAddItemDataView: method of AddSportDelegate, which in turn should push the correct ViewController onto the _addItemNavController stack. But, as I note in a comment in the code, the retain count of _addItemNavController at that moment is 0.
Note: I realize this code has memory leaks. I deleted some release lines for the sake of brevity. I also haven't included the code for the view controller that is supposed to be getting pushed, since it doesn't have anything at the moment beyond a UILabel identifying that it is the right View Controller.
AddItemDelegate.m
#synthesize addItemNavController = _addItemNavController;
- (void)showAddItemViewController:(UIViewController *)viewController
{
_parentVC = viewController;
[_parentVC retain];
tc = [[AddItemTableViewController alloc] init];
UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithTitle:#"Cancel" style:UIBarButtonSystemItemDone target:self action:#selector(cancelAdd)];
tc.navigationItem.leftBarButtonItem = cancelButton;
tc.title = #"Select a Category";
_addItemNavController = [[AddItemNavController alloc] initWithRootViewController:tc];
tc.superViewController = _addItemNavController;
[_parentVC.navigationController presentModalViewController:_addItemNavController animated:YES];
}
- (void)showAddItemDataView:(SportCategory *)category
{
[category retain];
UIViewController *vc;
if (category.name == #"Soccer") {
vc = [[AddSoccerDataViewController alloc] init];
}else{
vc = [[AddBaseballDataViewController alloc] init];
}
//retain count already 0
NSLog(#"retain count: %i", [_addItemNavController retainCount]);
[_addItemNavController.navigationController pushViewController:vc animated:YES];
}
AddItemTableViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
_addItemDelegate = [[AddItemDelegate alloc] init];
SportCategory *soccer = [[SportCategory alloc] initWithCategoryName:#"Soccer"];
SportCategory *baseball = [[SportCategory alloc] initWithCategoryName:#"Baseball"];
_categories = [[NSArray alloc] initWithObjects:soccer,baseball,nil];
[self.tableView reloadData];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
SportCategory *selectedCategory = [_categories objectAtIndex:[indexPath row]];
[_addItemDelegate showAddItemDataView:selectedCategory];
}
I am going to take a shot at this.
if (category.name == #"Soccer")
I come from a java background, but I know a little objective - c. I thought you can't compare strings with == which would mean your view controller was never created. Maybe try a isEqualToString method.
That is my only thought, I could be wrong. But Best of Luck.
The '==' operator isn't the good way to compare strings, but anyway your code should fall into the else part.
About your question, _addItemNavController must be nil because your NSLog prints 0 for its retain count.
Is the method -(void)showAddItemViewController:(UIViewController *)viewController called somewhere ?
Your view controller doesn't seem to be initialized.
A bit of sleep helped me find the problem. There were actually two:
1) The final line in AddItemDelegate read:
[_addItemNavController.navigationController pushViewController:vc animated:YES];
However, _addItemNavController IS the navigation controller, so the '.navigationController' part needed to be deleted.
2) I also needed to assign tc.addItemDelegate to self in showAddItemViewController.
I have spent several hours on this, and tried various things. I can confirm that the didSelectRowAtIndexPath is indeed being run, and the specific object I am looking for is being returned.
The bit that isn't doing anything is the part where I am trying to display the SensDetailViewClass view. It runs the code, but the viewDidLoad method in SensDetailViewClass.m doesn't run, and the view doesn't change.
I would like to have the SensDetailViewClass displayed. I can confirm that the .xib file's owner is the SensDetailsViewClass.
Please help. Here's the code.
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// get the selected item
Sens *info = [_sensInfos objectAtIndex:indexPath.row];
// initialise the detail view controller and display it
SensDetailViewClass *details = [[SensDetailViewClass alloc] initWithNibName:#"MainWindow" bundle:nil];
// set the title of the page
[details setTitle:info.heading];
details.selectedSens = info;
[self.navigationController pushViewController:details animated:YES];
[details release];
}
UPDATE: I got it to work by using this mechanism:
[self presentModalViewController:details animated:YES];
SensDetailViewClass *details = [[SensDetailViewClass alloc] initWithNibName:#"SensDetailViewClass" bundle:nil];
[self.navigationController pushViewController:details animated:YES];
i think you are fresher so nedd to check the link of tutorial
http://www.icodeblog.com/2008/08/03/iphone-programming-tutorial-transitioning-between-views/
Are you sure your SensDetailViewClass class has MainWindow as its .xib file?
Please check it and replace nib name `
initWithNibName:#"MainWindow"
in above code
Thanks,
1 ) Are you sure y*ou have the navigation comptroller in the app* or its just the View Based application.
IF this is ok then ,
2)
// initialise the detail view controller and display it
SensDetailViewClass *details = [[SensDetailViewClass alloc] initWithNibName:#"You-Xib name for this View" bundle:nil];
// set the title of the page
[details setTitle:info.heading];
details.selectedSens = info;
[self.navigationController pushViewController:details animated:YES];
[details release];
I am having problems with getting a detail view to load using pushViewController. At first, I thought pushViewController was not working. BUT, then I tried using a different view controller and it worked. I can tell from tracing that the problem view controller is never loaded at all. In other words, I tried to eliminate the possibility that there was some error in the view controller by NSLoging in that object and I never see anything.
Does anyone have any ideas?
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
/*
NSLog(#"hsitkjsdfkljlkd");
if (childController == nil)
childController = [[salesViewController alloc] initWithNibName:#"salesView" bundle:nil];
//NSUInteger row = [indexPath row];
[self.navigationController pushViewController:childController
animated:YES];
*/
/*
//modal = blocking
salesViewController *otherVC = [[salesViewController alloc] initWithNibName:#"salesView" bundle:nil];
//must set sale type
otherVC.strSaleType = #"Voice";
[self presentModalViewController: otherVC animated:YES];
//No close. By design, it is up to the otherVC to close itself
*/
//tipCalcViewController *detailViewController = [[tipCalcViewController alloc] initWithNibName:#"tipCalcView" bundle:nil];
salesViewController *detailViewController = [[salesViewController alloc] initWithNibName:#"salesView" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
}
Just Check the
- (void)viewWillAppear:(BOOL)animated
{
}
of the salesViewController.
you are doing something wrong in this..
put the debugging point in the viewWillAppear and run it. you can get the error line..
just try it......Surely it will work for u...
salesViewController *detailViewController = [[salesViewController alloc] initWithNibName:#"salesViewController" bundle:nil];
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
Also make sure you are giving the IBOutlet connection to UIView.
In my case I had several IBOutlets that I removed from the Header file and forgot to remove the connection to these non-existing outlets in Interface Builder. So removing the obsolete outlets fixed the problem in my case.
When you're pushing from ViewController1 to ViewController2 then the code will be used like this so try this code,
ViewController2 *vw2=[[ViewController2 alloc]initWithNibName:#"ViewController2" bundle:nil];
[self.navigationController pushViewController:vw2 animated:YES];
The Above code may be written on Click event of button or on didSelect delegate of UITableView