Crashing after dismissing a Modal View Controller - iphone

Im presenting and dismissing a Modal View Controller. I use delegation so I dismiss the modalView at the Parent.
- (void)launchDrawingSection{
drawingSectionViewController = [[DrawingSectionViewController alloc] init];
drawingSectionViewController.modalTransitionStyle = UIViewAnimationTransitionFlipFromLeft;
drawingSectionViewController.drawingModalDelegate = self;
[self presentModalViewController:drawingSectionViewController animated:YES];
}
- (void)didDismissDrawingModalView{
NSLog(#"didDismissDrawingModalView");
[drawingSectionViewController release];
[self dismissModalViewControllerAnimated:YES];
}
The app crashes after the dealloc method in the ModalView gets called.
Am I doing something wrong with the way I present and dismiss a Modal View Controller? Any idea?

Don't release before dismiss.
- (void)launchDrawingSection{
drawingSectionViewController = [[DrawingSectionViewController alloc] init];
drawingSectionViewController.modalTransitionStyle = UIViewAnimationTransitionFlipFromLeft;
drawingSectionViewController.drawingModalDelegate = self;
[self presentModalViewController:drawingSectionViewController animated:YES];
[drawingSectionViewController release];
}
- (void)didDismissDrawingModalView{
NSLog(#"didDismissDrawingModalView");
[self dismissModalViewControllerAnimated:YES];
}

Your fundamentals of Modal View Controller is not clear.
If you are using delegate protocols only to inform the drawing sections's parent control to dismiss the drawing section controller, then this is something useless. Because, the following thing does your job without use of delegates.
// Present drawing section.
- (void)launchDrawingSection{
drawingSectionViewController = [[DrawingSectionViewController alloc] init];
drawingSectionViewController.modalTransitionStyle = UIViewAnimationTransitionFlipFromLeft;
drawingSectionViewController.drawingModalDelegate = self;
[self presentModalViewController:drawingSectionViewController animated:YES];
[drawingSectionViewController release];
}
// (Put this in Drawing Section View Controller). This function dismisses drawing section.
- (void)dismissActionEvent{
// Drawing section view controller is asking its parent to dismiss it.
[self.parentViewController dismissModalViewControllerAnimated:YES];
}
To understand clearly how presenting and dismissing modal view controller's work, refer to my answer here

Related

DismissmodalViewController donot remove the modal View

I have been figuring out this since yesterday but have not got that correct yet.
I have added the modalviewcontroller for my loading view controller on top of my tab bar controller and it works fine.
Added the code in app Delegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions {
[navController.navigationBar setTintColor:[UIColor blackColor]];
[window addSubview:rootController.view];
[window makeKeyAndVisible];
LoadingViewController *lvc = [[LoadingViewController alloc] initWithNibName:#"LoadingView" bundle:nil];
// Delegate added here
lvc.loadingDelegate = self;
[rootController presentModalViewController:lvc animated:YES];
[self URL];
[lvc release];
return TRUE;
}
Now I do my parsing and when its done I call the following code in different view name XMLParsingView.m where the parsing got over.
- (void)handleLoadedApps
{
LoadingViewController *loading = [[[LoadingViewController alloc] init] autorelease];
//delegating to let the load view controller know to dimiss itself by defining disappear method in protocol
[loading.loadingDelegate disappear];
}
and in loading view controller I have method which calls dismissModalViewControlAnimated:
-(void)disappear{
[activity stopAnimating];
[activity removeFromSuperview];
[self removeFromSuperview];
[self dismissModalViewControllerAnimated:YES];
}
But for some reason it will never remove the view and not load it back to my tab bar controller.
Really need help here if any one have come across such issues.
Sagos
In your code you seem to create, without a nib, a new LoadingViewController and immediately go and dismiss it. In your app delegate you create your first loadingViewController with a nib, present it modally on rootController and then release it. Since you want to dismiss it outside your app delegate you have
3 choices, (hardest to fastest and most sane)
a) Key-Value-Observing on a property of XMLParsingView from LoadingViewController to remove itself when the task finishes.
b) Use delegation to inform the LoadingViewController when the task finishes to dismiss itself.
c) Fetch your rootController from your [[UIApplication sharedApplication] delegate], which means you must expose rootController as a property or through a method, and make rootController dismiss your modal.
You need to call dismissModalViewControllerAnimated on the rootViewController, not the loading view controller.

iphone loss of tabbar during uimodaltransition

Okay, working on a transition between a view with a tabbar and another view which is to be an information/about view. I have the code to transition from the view with tabbar and to transition back to previous view, but during the transition back I lose the tabbar at the bottom. Not sure exactly how to approach this with the tabbar in the MainWindow.xib
E.g.:
(IBAction)backButtonPressed:(id)sender
{
TablesViewController *tvc = [[TablesViewController alloc] initWithNibName:#"TablesView" bundle:nil];
tvc.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:tvc animated:YES];
[tvc release];
}
Thanks,
np
Try presenting the modal transition from the containing instance of UITabBarController and not the UIViewController the action was triggered from.
- (IBAction)backButtonPressed:(id)sender
{
TablesViewController *tvc = [[TablesViewController alloc] initWithNibName:#"TablesView" bundle:nil;
tvc.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self.tabBarController presentModalViewController:tvc animated:YES];
[tvc release];
}
I had the exact same problem, did a ugly solution:
- (IBAction)backButtonPressed:(id)sender {
[self.navigationController dismissModalViewControllerAnimated:YES];
}

presenting viewController after contact has been selected in peoplePickerNavigationController?

I am having a little problem -
(BTW i have looked on
How can I present a modal view controller after selecting a contact?
but it didnt help me)
Basically i want to let the user select a contact using the - peoplePickerNavigationController. after the selection i want to presentModalViewController that will use the personRef data.
i can see that the "add person" method get called but the iphone does not present the view.
UPDATE - It works if i cancel the animation in the Dismiss dismissModalViewControllerAnimated and in the presentModalViewController, but then it looks pretty ugly.
this is the function called after the user selects the contact -
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)personRef {
TempREcordId = ABRecordGetRecordID(personRef);
BOOL hasDeleteDate = [GlobalFunctions CheckToSeeIfInHiBye:TempREcordId];
if (hasDeleteDate) {
[GlobalFunctions alert:NSLocalizedString(#"", #"") ];
}else{
[self addCustomValuesAfterSelection];
[self dismissModalViewControllerAnimated:YES];
}
return NO;
}
this is the function called but still the view is not presenting -
- (void)addPerson {
NSLog(#"#2");
AddViewController *addViewController = [[AddViewController alloc] initWithStyle:UITableViewStyleGrouped];
addViewController.delegate = self;
// Create a new managed object context for the new book -- set its persistent store coordinator to the same as that from the fetched results controller's context.
NSManagedObjectContext *addingContext = [[NSManagedObjectContext alloc] init];
self.addingManagedObjectContext = addingContext;
[addingContext release];
[addingManagedObjectContext setPersistentStoreCoordinator:[[fetchedResultsController managedObjectContext] persistentStoreCoordinator]];
addViewController.person = (Person *)[NSEntityDescription insertNewObjectForEntityForName:#"Person" inManagedObjectContext:addingContext];
addViewController.hiByeGroupId = [dataSource hibyeGroupId];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:addViewController];
[self.navigationController presentModalViewController:navController animated:YES];
[addViewController release];
[navController release];
}
thank you very much.
Just don't dismiss the people picker and present your controller modally on top of it. If you afterwards dismiss your controller at some point dismiss the people picker instead (from the caller/parent) and your ViewController will be dismissed too.
From the Apple Docs:
dismissModalViewControllerAnimated: …
If you present several modal view controllers in succession, and thus build a stack of modal view controllers, calling this method on a view controller lower in the stack dismisses its immediate child view controller and all view controllers above that child on the stack. When this happens, only the top-most view is dismissed in an animated fashion; any intermediate view controllers are simply removed from the stack.
Although by picking a person, the picker dismisses, the key is to dismiss it yourself in the delegate callback, after picking a person and than present your controller
- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController*)peoplePicker didSelectPerson:(ABRecordRef)person {
[self.navigationController dismissViewControllerAnimated:YES completion:^{
ContactDetailViewController * vc = [[ContactDetailViewController alloc] initWithWithABRecord:person];
vc.delegate = self;
UINavigationController * nc = [[UINavigationController alloc] initWithRootViewController:vc];
[self.navigationController presentViewController:nc animated:YES completion:^{
}];
}];
}
I suppose you just have to wait until the people picker disappeared by finishing its animation which it indicates by calling viewDidDisappear. If you override and hook up in there, you should be save to present your modal controller.

Modal view controller returning

I have the following code where I display a view controller within a navigation controller.
Just for the test I display it for 3 seconds and then dismiss it.
What is happening is that it disappearing - and then reappearing after a second or so.
What am I doign wrong?
- (void) test
{
[myNavCtrl dismissModalViewControllerAnimated:YES];
}
- (void) viewDidAppear:(BOOL)animated
{
MyViewController *ctrl = [[MyViewController alloc] init];
[ctrl setDelegate:self];
myNavCtrl = [[UINavigationController alloc] initWithRootViewController:ctrl];
[myNavCtrl setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
[self presentModalViewController:myNavCtrl animated:NO];
[ctrl release];
[myNavCtrl release];
[self performSelector:#selector(test) withObject:nil afterDelay:3];
}
The viewWillAppear method is called every time the controller's view appears so you've created a loop. The view appears, it calls the modal view which covers the calling view. When the modal view disappears, the calling view controller's viewWillAppear gets called again. Lather, rinse, repeat.

Dismissing UIPopoverController when using ABNewPersonViewController

I have an "add Contact" button which when on iPhone I present a navigation controller with root view controller of an ABNewPersonController modally.
If on iPad I have got a popover which I can display with the new person controller inside - nice.
The problem comes when trying to dismiss.
I can dismiss the popover when touching done or cancel within my implementation of didCompleteWithNewPerson using;
if(self.popoverController != nil)
[popoverController dismissPopoverAnimated:YES];
However, this doesn't dismiss when touching outside the popover.
I've returned YES for my popoverControllerShouldDismissPopover method and set the delegate of my popover to this. I've put an NSLOG inside this method and it's not dropping in there - Am I missing something?
Does anyone know how to dismiss the popover when touching outside?
Update - More Code
-(IBAction)contactsClicked:(id) sender{
ABNewPersonViewController *newPersonView = [[ABNewPersonViewController alloc] init];
[newPersonView setNewPersonViewDelegate:self];
[newPersonView setDisplayedPerson:newPerson];
UINavigationController *addContactNavController = [[UINavigationController alloc] initWithRootViewController:newPersonView];
[newPersonView release];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
if(self.popoverController == nil){
UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:addContactNavController];
self.popoverController = popover;
self.popoverController.delegate = self;
[popover release];
}
CGRect frame = [sender frame];
[popoverController presentPopoverFromRect:frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionRight animated:YES];
} else {
[self presentModalViewController:addContactNavController animated:YES];
[addContactNavController release];
}
}
-(void)unknownPersonViewController:(ABUnknownPersonViewController *)unknownPersonView didResolveToPerson:(ABRecordRef)person{
[self dismissModalViewControllerAnimated:YES];
}
-(void)newPersonViewController:(ABNewPersonViewController *)newPersonViewController didCompleteWithNewPerson:(ABRecordRef)person {
NSLog(#"DONE OR CANCEL clicked!!!!"); //prints
if (self.popoverController != nil) {
[popoverController dismissPopoverAnimated:YES];
}
[self dismissModalViewControllerAnimated:YES];
}
The Done and Cancel buttons of the new person controller work, dismissing the controller and the popover (when running on iPad). I guess this means the delegate for the ABNewPersonViewController is implemented correctly. (?)
I'm guessing that I may be confusing the issue by having multiple controllers and my popover delegate method is getting hidden or something?
Thanks in advance
EDIT - Delegate method
-(BOOL)popoverControllerShouldDismissPopover:(UIPopoverController *)thePopoverController{
NSLog(#"clicked outside the popover");//never prints
return YES;
}
From the docs:
Taps inside the popover window do not automatically cause the popover to be dismissed. Your view and view controller code must handle actions and events inside the popover explicitly and call the dismissPopoverAnimated: method as needed.
You should use the popover delegate methods –popoverControllerShouldDismissPopover: to listen for when it's about to be dismissed and do your saving etc. there.
Also, you should use self not this.