presentModalViewControllver over a modalViewController works only once - iphone

For sake of simplicity I have 3 UIViewControllers named, vc0, vc1, vc2. My Flow of operations is a button in vc0 calls
[vc0 presentModalViewController:vc1]
Then in vc1 I have another button in vc1 that calls
[vc1 presentModalViewController:vc2]
In both vc1 and vc2 I have an X button that calls
[self dismissModalViewController];
Now the first run threw that flow is fine, vc1 is presented modally, followed by vc2 after the correct button presses. Dismissing the views also behaves correctly. However, when I attempt to start the flow all over again I'm unable to present vc2 modally from vc1. Has anyone else run into a similar problem before?

I think You might be missing the allot + init for the view controllers that you want to present

Related

How does a modal view controller work with the stack?

Im new to iPhone programming. And, im trying to make a game with like 200 levels. I want to use modal segueing because i dont want the naviagational bar at the top, and also i want the cross dissolve animation. Say I have vc one. And then I have vc 2
ok, so vc 1 segues modally to vc 2
and then i have a button on vc 2 to segue back to vc 1
so, does the program know to pop vc 2 off the stack? or did i just create a memory leak so that now vc1, vc2, and vc1 are on the stack instead of just vc1.
and then still also if i had vc1 to vc2, and vc2 to vc3, and in vc3 i have a button that goes back to vc 1, will the program pop both vc 2 and vc 3 off the stack? or will 4 be on the stack? And anyways, since with a modal segue theres no real back button (like in a navigational push segue theres always a back button on the navigational bar), does modal segueing even have a stack?
I mean, or is it independent? Like, say vc segues to vc2, and vc2 to vc3. Now, is vc 2, and 1 even on the stack? or is it just vc3?
sorry, im just a little confuzzled about all this, and im not sure how to make my game. Because if i have 100 view controllers with different levels, then surely in order to have modal segueing I would need to code some popping off vcs off the stack each time i segue right, so that i dont end up with 100s of controllers on the stack? And i dont even know how to tell my program how to pop off view controllers.
So a modal segue is mainly for presenting content that interrupts the usual flow of the application. It isnt really a good fit for presenting several view controllers sequentially because, as you say, if you have a segue that goes back to the first view controller it doesn't pop anything off the stack.
You want to look for one of the Apple provided View Controller containers to see which one would best fit going through a sequential list of view controllers.
The page view controller is useful because it only keeps one or two view controllers loaded at a time and as of iOS 5 you can set the transitionStyle property to 'UIPageViewControllerTransitionStyleScroll' to scroll left and right (or up and down) between view controllers.
If you dont like the view controllers apple provides for this then look at the documentation for UIViewController about how to write your own custom container view controller. This way you can define your own stack, pop the stack as needed and have a dissolve transition.
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/Reference/Reference.html%23//apple_ref/doc/uid/TP40006926-CH3-SW81

Navigation controller stack, pushing 2 views on at once. So you can skip from VController1 straight to VController3

I've got a hierarchy of 3 ViewControllers on a UINavigationController app.
Start in VC1, from there you can load VC2. In VC2 you can load VC3.
You can navigate backwards through the VC's by pressing the left nav button on the navbar.
But the designer wants to be able to jump from VC1->VC3, and then if you press the left navbar button to go back it will take you to vc2.
Is it possible to have have this kind of navigation with a NAV controller?
If the user wants to go VC1-VC3 can i push both VC2 and then VC3 onto the navigationController stack so that the navigation is maintained correctly.
Also if the user wants to go from VC3->VC1 can i pop both VC3 and then VC2 off the navigationController stack so that VC1 displays?
First - tell your designers that this kind of navigation is confusing for the users and they should take some more usability and UX classes. Second - yes it's possible - the easiest way would be to call
[navigationController setViewControllers:newViewControllers animated:YES];
This will replace the entire navigation stack, so ensure that it contains [VC1, VC2, VC3] (and whatever else might happen to be before them)
The normal back button will pop to the previous view controller. You could make a left bar button in you V3 which will pop to a given view controller in your hierarchy using the UINavigationController method (giving your V1 instance as viewController)
- (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated
Push BOTH VC2 and VC3 onto the stack to preserve the navigation when pressing the back button. To go from VC3 to VC1 you can use...
[navigationController popToViewController:vc1 animated:YES];
or if VC1 is the root...
[navigationController popToRootViewControllerAnimated:YES];

Jumping back and displaying a VC more that 2 layers underneath the top VC

I have the base ViewController which i my main menu(VC1).
From there I navigate to another VC which displays a UITable(VC2). From here i can call
[self.parentViewController dismissModalViewControllerAnimated:YES];
To move back to the main menu. That works fine.
If i load another VC(V3) with displays a UIWebView from VC2 and want to jump back to the main menu(VC1), how can this be done in the best way?
So I navigate VC1->VC2->VC3 and then want to jump VC3->VC1.
My app doesn't have a UINavigationViewController or anything like that.
Many Thanks,
-Code
You could try creating a method in the parent vc (vc2) that you call from vc3 that does the following:
-(void)dismissTwo
{
[self dismissModalViewControllerAnimated:NO];
[self.parentViewController dismissModalViewControllerAnimated:YES];
}
That's untested, but give it a shot.
Its tricky if you used navigation controller you could have popped to root view controller using poptorootviewcontroller.
However in your case if you can implement a delegates for VC2 and VC3. In the delegate for VC3 in VC2 dismiss VC3 and call delegate of VC2 which is implemented in VC1.
So basically the flow is as follows
Create VC1
When you create VC2 from VC1 assign delegate to VC1
When you create VC3 from VC2 assign delegate to VC2
From this point on you can pass messages in a cleaner way between the view controllers.

UIViewControllers tripping over each other

Need some best practice advice here...
Navigation based application. Root view is a UITableView where user can drill down to a detail UIViewController (call it VC1). User wants to initiate some task but it may require additional info before it can proceed. If so then VC1 allocs & presents modal VC2 using the "flip" transition holding a strong reference to VC2 in a property.
All fairly standard. Here's where I'm running into trouble. Once user fills out required info in VC2 the app can either continue on to a MFMailComposeViewController or flip back to VC1. If they continue to MailCompose then when that dismisses it should return to VC1.
VC2 has a weak reference to VC1 and the problem arrises when VC2 tries to dismiss itself and present MFMailComposeViewController:
[self dismissModalViewControllerAnimated:YES];
[VC1 performSelector:#selector(showMailModalView) withObject:nil afterDelay:0.2];
I get a EXC_BAD_ACCESS on VC1 because, apparently, my weak reference to VC1 has already been dealloc'd even though VC1 has strong reference to VC2!?!
So my question is...how should this be handled? Would the delegate pattern be better? How would that be triggered?
Note: VC1 is quite large and VC2 isn't often needed so I'm trying to keep VC2 as separate as possible from VC1 (including its own NIB).
VC2 has a weak reference to VC1 and the problem arrises when VC2 tries
to dismiss itself and present
MFMailComposeViewController:
What you have is a circular dependency, since VC1 knows about VC2 and then you let VC2 know about VC1. And When you have circular dependencies, you get all sorts of problems.
You should be using the delegate pattern here. When VC1 presents VC2, it should make itself VC2's delegate. When VC2 is done and wants to dismiss itself, it should let the delegate take care of that operation. In other words, the thing that shows VC2 should be the thing that dismisses VC2. VC2 should be implemented in such a way that it shouldn't know what presented it, only that what presented it will be in charge of dismissing it.
Two similar answers I've given recently:
Pop-up modal with UITableView on iPhone
call method in a subclass of UIView
I've run into the same problem and I'm trying to recall how I fixed it.
You might try calling:
[self.parentViewController dismissModalViewControllerAnimated:YES]
Or could you have your showMailModalView method handle dismissing the current modal view controller before showing the mail composer?

what method does navigationcontroller fire

I have a navigationController and 3 View controllers. VC1 pushes VC2 and VC2 uses PresentModalViewController to display the 3rd VC
When VC2 uses presentModalViewController to show VC3, is the VC3 actually pushed on the navigationcontroller stack?
viewdidload of VC3 is called only 1st time. My goal is to show VC3 with a new imageView everytime. Where do I add the code to do that? viewdidappear and viewwillappear of VC3 is not fired either
It is my understanding that VC3 will be in the view hierarchy of VC2 and not the navigationController. In order to be added to the view hierarchy of the navigationController you would have to push VC3 onto it.
viewDidLoad should only be called once, unless the nib file itself was unloaded from memory, due to low memory. The documentation states that viewWillAppear and viewDidAppear should be called on VC3, so I don't know why they are not.
Update
I just tested and VC3 does have -(void)viewDidAppear:(BOOL)animated called. Make sure that the signature on the selector is correct