I am using a tab based application that shows a presentModalViewController called "overview" that has 2 buttons on it .
In order to call it I am using the following code in app delegate:
Overview *overview = [[Overview alloc] initWithNibName:#"Overview" bundle:nil];
[self.tabBarController presentModalViewController:overview animated:YES];
When overview shows up, it has a button called that gets clicked and I am using the following code:
-(IBAction) btnLoginPressed{
[self dismissModalViewControllerAnimated:YES]; //get rid of view
Login *login = [[Login alloc] initWithNibName:#"Login" bundle:nil];
[self.tabBarController presentModalViewController:login animated:YES];
[login release];
}
However the login prsentModalViewController never shows up. Can someone explain why and what I can do to show it?
Thanks
When you present a modal view controller, you do it from the view controller currently in the view.
Assuming your second modal display of a view controller is happening in Overview.m change your code to the following:
-(IBAction) btnLoginPressed {
Login *login = [[Login alloc] initWithNibName:#"Login" bundle:nil];
[self presentModalViewController:login animated:YES];
[login release];
}
You don't need to dismiss Overview first, and in fact you shouldn't as it the animations won't work in conjunction with each other.
When you ultimately dismiss login (or however deep you want to go), you send dismissModalViewController:animated: as high up as you need to. To get back to the tab bar's controller use:
[self.tabBarController dismissModalViewController:animated]
It would be well beyond the scope of your question and the time I have to answer but you should take some time and really study the docs on implementing View Controllers. I definitely recommend following Apple's code style guidelines as one suggestion to make your code much more readable (e.g. overviewViewController vs overview). It's also clear you're just learning so keep at it.
Related
I am trying to add a registration page & a verification page to my app that has a 3 views that can be switched to and from using a UITabBarController. The registration page should only be shown once in this app's life time. Once a user is registered, this view will go away and be replaced by a verification page. Once a users identity is verified, a user can use the app.
Now in AppDelegate I have the following code to present the registration page to the user:
RegistrationPage *registration = [[RegistrationPage alloc] initWithNibName:#"RegistrationPage" bundle:nil];
[self.window.rootViewController presentViewController:registration animated:YES completion:nil];
After the user filled the registration page and pressed the submit button, the following code is used to dismiss the registration page and present the verification page:
VerificationPage *verification = [[VerificationPage alloc] initWithNibName:#"VerificationPage" bundle:nil];
[self dismissViewControllerAnimated:YES completion:^{
[self addVerificationPage];
}];
-(void) addVerificationPage
{
VerificationPage *verification = [[VerificationPage alloc] initWithNibName:#"VerificationPage" bundle:nil];
[self presentViewController:verification animated:YES completion:nil];
}
However the verification page just never shows up. Can someone help me with this?
I have also tried this in the registration page, does not work either:
VerificationPage *verification = [[VerificationPage alloc] initWithNibName:#"VerificationPage" bundle:nil];
[self dismissViewControllerAnimated:YES completion:^{
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:verification animated:YES]
}];
Most likely is an issue caused by attempting to present the VerificationPage at the same time as you dismiss the RegistrationPage. From the Apple documentation:
Dismissing a view controller dismisses not only that view controller but also any view controllers it presented.
As a result, there's two possible orders, either of which will result in failure - either the VerificationPage is created and presented, then the RegistrationPage is dismissed - taking the presented VerificationPage with it. Alternatively, the RegistrationPage is dismissed and destroyed, then the presentViewController call is sent through to it - resulting in failure as the RegistrationPage is no longer a valid ViewController.
To resolve, either leave the RegistrationPage open and present the VerificationPage over it (not ideal, but it will work), or signal the AppDelegate or a ViewController higher up the chain (you can use self.presentingViewController) to do the presenting instead.
I have this same piece of code in two different parts of my app.
In one section it is executed perfectly, and in the other it is completely ignored. I've put in a breakpoint and watched the program go through each line of this code without loading the next xib/class it is supposed to.
Here is the code:
UIViewController *nextController = [[ClassNameViewController alloc] initWithNibName:#"MatchingView" bundle:nil];
[nextController performSelector:#selector(setDelegate:) withObject:self];
[self presentModalViewController:nextController animated:YES];
Any ideas why this might be getting ignored and not presenting my viewController?
Try using ..
[self.navigationController presentModalViewController:nextController animated:YES];
I had this code in viewDidLoad and moving it to viewDidAppear made it work.
My app is crashing when I dismiss a ModalViewController via:
[self.parentViewController dismissModalViewControllerAnimated:YES];
This modal view-controller ("MVC") is presented when a user clicks on one of the cells of a UINavigationController ("NavRoot") - here's the code for that:
MVC *modalView = [[MVC alloc] initWithNibName:#"MVC" bundle:nil];
[self.navigationController presentModalViewController: modalView animated:YES];
[modalView release];
The "modalView" which is loaded contains only 2 objects: a UIWebView object and a "DONE" button, which when clicked-on does the dissmissing via:
[self.parentViewController dismissModalViewControllerAnimated:YES];
Except when I click on "DONE" - the app crashes.
When I run Instruments with NSZombies I do see the retain count reaches -1 but I can't tell what's causing this over-release.
The only thing I found which solves the problem is to either add a "[modalView retain]" statement in "NavRoot" - which is the viewController doing the presenting of modalView:
MVC *modalView = [[MVC alloc] initWithNibName:#"MVC" bundle:nil];
[self.navigationController presentModalViewController: modalView animated:YES];
[modalView retain]; // <<== new 'retain' statement
[modalView release];
or just simply never releasing modalView in the first place:
MVC *modalView = [[MVC alloc] initWithNibName:#"MVC" bundle:nil];
[self.navigationController presentModalViewController: modalView animated:YES];
// commenting out the 'release':
// [modalView release];
Both of these options throw flags when I run "Analyze" ("Potential leak of an object allocated on line 34"...) but they do fix the problem.
Still, I worry about this causing the app to be rejected by Apple from the App Store.
Any ideas on what may be causing the over-release? Or how I might further try to isolate / identify the problem?
attaching an image of Instruments/Zombies report:
Are u using iOS 5? I had the same problem when I switched an app from ios4 to 5.
ParentViewController is now called presentingViewController
What you can do though is in your modal view just call [self dismissModalViewController] and it should dismiss itself. I'm not 100% about that and can't check as I'm not near my mac, but I recall reading it in the docs,
If you do
[self.navigationController presentModalViewController: modalView animated:YES];
Then you should dismiss it like
[self.navigationController dismissModalViewControllerAnimated:YES];
Rather than
[self.parentViewController dismissModalViewControllerAnimated:YES];
Where are you trying to dismiss the view from? The actual modalView or the parentView? It seems to me that you are trying to dismiss a modal view that has already been dismissed and subsequently released.
To dismiss a modalViewController I simply just do: [self dismissModalViewControllerAnimated:YES];.
[self dismissModalViewControllerAnimated:YES] does not work on iOS 5.
I have built a category that add presentingViewController on iOS 4. (It disables itself on iOS 5.)
Just include 2 files, and it works seamlessly.
Please see backward-modal.
I hope this benefits you as much as it does to me; It makes your code more clean!
i am trying and trying.... but no result yet.
i have a view with a navigationcontroller and -bar. in addition there is a tableview.
if you click on a row, the iphone email function is getting startet by using the email example from apple (MailComposerViewController.h and .m).
it opens and i am able to send or cancel the mail. after that the "dismissModalViewControllerAnimated" methode is dismissing the emailing view. everything looks right, i am in the previous view now, BUT:
when i want to use buttons from the navigationitem or if i want to add rows to the tableview, the app is crashing without any error message.
do i have to set something back or to "remove" something which is still there because of the mailing view?
it's really strange and i am searching now for hours....... :-(
thank you very much in advance!
hopefully someone has an idea.
EDIT:
ok, here i have the code now:
in a tableview which is included in a navcontroller i have following lines to open first a Subclass of UIViewController:
- (IBAction)Action:(id)sender
{
DetailViewController *editViewController = [[DetailViewController alloc] initWithNibName:#"TripDetailViewController" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:editViewController animated:YES];
editViewController.navigationItem.prompt = #"Details";
[editViewController release];
}
in the DetailViewController following action is processed when the user clicks on the button:
- (IBAction)mailTrip:(id)sender {
MailComposerViewController *mailComposer = [[MailComposerViewController alloc] init];
[[[self view] window] addSubview:[mailComposer view]];
[mailComposer showPicker:sender];
}
when i press the related button, the MailComposerViewController pushes up correctly. all functions of the MailComposerViewController are working correct.
but when i send or cancel the mail and the MailComposerViewController disappears, my previous view doesn't work anymore.
in the MailComposerViewController-Example from apple the MailComposerViewController just disappear and the previous view is working fine again.... :-(
ok, i found the stupid simple problem.
the MailComposer-View was after dismissing it still over the previous view.
i did set the propert hidden after dismissing and now it works...
[self dismissModalViewControllerAnimated:YES];
[[self view] setHidden:YES];
but i am really not sure if this is the right way to do it...
I am developing a Window Based app for iPhone. I use Interface Builder to build Interface. I want to call a new screen with a Button Action. How can I call the screen with Button action ?
By pushing the new controller onto the top of the stack of windows. For example:
EnterNameController *newEnterNameController = [[EnterNameController alloc] initWithNibName:#"EnterName" bundle:[NSBundle mainBundle]];
[[self navigationController] pushViewController:newEnterNameController animated:YES];
Apple has an extraordinary amount of sample code, and this question (as well as many others) could easily be solved by simply visiting Apple's iPhone dev site.
iPhone Dev Site
If you are using a navigation controller, push it onto the navigation controller's stack, as alamodey suggested.
If you want it to be a modal controller (that is, slide up from the bottom and cover the previous controller's view, like the Bookmarks screen in Safari), present it as a modal view controller:
[self presentModalViewController:myNewController animated:YES];
When you want to bring the old controller back, dismiss the modal view controller. From inside the modal view controller:
[self.parentViewController dismissModalViewControllerAnimated:YES];
If you don't want to do either, just remove the current controller's view from the window and add the new controller's:
UIView * containingView = self.view.superview;
[self.view removeFromSuperview];
[containingView addSubview:myNewController.view];
If you go this route, you may want to look into +[UIView beginAnimations:context:], +[UIView setAnimationTransition:onView:], and +[UIView commitAnimations] (if I recall the method names correctly--check the documentation) to animate the transition. You should almost always animate any switch between screens in iPhone OS.
(work in .m class)
#import "classtocall.h"
- (IBAction)ButtonPressed:(id)sender
{
classtocall *mvc = [[classtocall alloc]initWithNibName:#"classtocall" bundle:nil];
[self presentModalViewController:mvc animated:NO];
}
(for window based application)
define in .h class
- (IBAction)ButtonPressed:(id)sender;
where "classtocall" is the class you want to call.
you just need to download sample applications from XCode help. Try Elements and UIcatalog. There are also other - type 'pushViewController' or 'addSubview' adn 'makeKeyAndVisible' in help and download samples
nextscreenViewController *login = [[self storyboard] instantiateViewControllerWithIdentifier:#"nextscreenidentifier"];
nextscreenidentifier.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController: nextscreenidentifier animated: YES];