I am developing iPhone app, where i got stuck at one point.
The error i am facing is, i have one presentViewController on which i have one button, on click of that button i am dismissing my presentViewController and after dismissing i want to push My view controller but it doesn't pushes.
Code on PresentViewController:
- (IBAction)ButtonClick:(id)sender {
[self dismissViewControllerAnimated:YES completion:^{
[Obj MethodCall];
}];
}
after dismissing PreviousViewController:
-(void) MethodCall
{
NSLog(#" -- MethodCall Success --");
[self.navigationController pushViewController:[[NewViewController alloc] init] animated:YES];
}
My log shows -- MethodCall Success -- but it does not pushes my view.
Where i am doing mistake ?
Please help and thanks for reading.
The problem with you is I think you are not having UINavigationController as a rootViewController of the viewController from which you have to navigate. So please try to add a UINavigationController as a parent view or rootView of the vieController from which you want to push another viewController.
- (IBAction)ButtonClick:(id)sender {
NewViewController *newView = [[NewViewController alloc] init]
[self presentViewController:newView animated:YES completion:nil];
}
Related
I got an error exc_bad_access,when i use dismissviewcontrolleranimated
the presentViewController code is:
TestViewController *testViewController=[[TestViewController alloc] init];
UINavigationController *nav=[[UINavigationController alloc] initWithRootViewController:testViewController];
[self presentViewController:nav animated:YES completion:^{
NSLog(#"presentViewController is finish");
}];
but,when i remove UINavigationController ,is error is disappear.
like this:
TestViewController *testViewController=[[TestViewController alloc] init];
[self presentViewController:testViewController animated:YES completion:^{
NSLog(#"presentViewController is finish");
}];
Thanks for help.
Present View Controller is presented over a "Root View Controller" not a UINavigationController.
You should present your VC from the Parent VC or Base VC like this
TestViewController *testViewController=[self.storyboard instantiateViewControllerWithIdentifier:#"storyboardIDofViewController"];//set the storyboard ID of the TestViewController in your storyboard by selecting attribute inspector after selecting the view controller.
[self presentViewController:testViewController animated:YES completion:^{
NSLog(#"presentViewController is finish");
}];
This is the correct way to present a VC from another VC.
UINavigationController have Push and Pull transitions and you are trying to apply Modal Transition to it.
I am trying to show navigation controller when i present PresentViewController for navigate a screen. I solved this problem, but i faced another problem. Problem is when i push to a screen that time back button is visible on next screen with navigation controller. But when i am trying to PresentViewController, that time navigation bar is visible but not back button.
Here is my code:
- (IBAction)clickMeAction:(id)sender
{
ViewController1 *viewcontrol = [self.storyboard instantiateViewControllerWithIdentifier:#"ViewID"];
//[self.navigationController pushViewController:viewcontrol animated:YES]; // this is for push to viewcontroller
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewcontrol];
[self presentViewController:navigationController animated:YES completion:nil]; // This is for modalviewcontroller
}
Here is my output:
with push:
with modal:
Please help me.
Method 1:
[navigationController presentViewController:navigationController animated:YES completion:^{
[navigationController setNavigationBarHidden:YES animated:NO];
}];
Method 2: in presentViewController
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.navigationController.navigationBarHidden = YES;
}
EDIT
After some more digging around it has become apparent that if i try to call a segue from the view controller class after a fast application switch to/from Safari i get an exception stating that the segue does not exist. It definitely does, in the VC that is loaded on screen, and i have checked the spelling and it's 100% correct.
What makes it even weirder is that if i call that exact same method from an IBAction it works fine.
Here's the code i am using:
-(void)goToPhotoPage{
[self performSegueWithIdentifier:#"twitterAuthComplete" sender:self];
}
If i call this when the app resumes i get an exception, however if i call it from this IBAction, attached to a UIButton, with doing nothing different the segue works as expected and no exception.
- (IBAction)twitterToPhoto:(id)sender
{
[self goToPhotoPage];
}
Arrrrgrghrhhgrgrg!
ORIGINAL QUESTION
I am working on an iPad application that uploads user photos to Facebook/Twitter.
As part of the process i have to jump to Safari to do OAuth for twitter, the app then jumps back via a specific URL and get's the tokens e.t.c
However for some reason when the application re-awakes i cannot trigger any segue's or manually load any VC's.
I have a success block in my AppDelegae which get's called when the upload is complete which calls a method in the VC to close a spinner and segue to the success view.
The spinner stops as expected, but no matter what i try i cannot get the segue to work.
Everything is hooked up, the segue has an ID and i get no error or exceptions in the console, just nothing happens. The only way i can get code triggered segue to work after this point is to use a user trigger one connect to a UIButton, after that one complete they start to work again.
Here is the code with callback in my AppDelegate:
- (void)postToTwitter:(NSString*)postText image:(UIImage*)image
{
NSData *data = UIImageJPEGRepresentation(image, 0.5);
[_twitter postStatusUpdate:postText
mediaDataArray:#[data]
possiblySensitive:nil
inReplyToStatusID:nil
latitude:nil
longitude:nil
placeID:nil
displayCoordinates:nil
uploadProgressBlock:^(NSInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite) {
} successBlock:^(NSDictionary *status) {
ViewController * vc = [[ViewController alloc]init];
[vc triggerSuccess];
} errorBlock:^(NSError *error) {
ViewController * vc = [[ViewController alloc]init];
[vc uploadFail:error];
}];
}
in the VC i have tried the following:
- (void)triggerSuccess
{
[self segueToSuccess];
}
- (void)segueToSuccess
{
[self hideMessage];
[self.navigationController performSegueWithIdentifier:#"approveSegue" sender:self];
}
As well as:
- (void)triggerSuccess
{
[self segueToSuccess];
}
- (void)segueToSuccess
{
[self hideMessage];
UIViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:#"done"];
[self.navigationController pushViewController:controller animated:YES];
}
In a moment of pure desperation i even tried:
- (void)triggerSuccess
{
[self segueToSuccess];
}
- (void)segueToSuccess
{
[self hideMessage];
//[self.navigationController performSegueWithIdentifier:#"approveSegue" sender:self];
[self dismissViewControllerAnimated:NO completion:nil];
[self.navigationController popToRootViewControllerAnimated:NO];
[self performSelector:#selector(segueToSuccessPart2) withObject:nil afterDelay:0.25];
}
- (void)segueToSuccessPart2
{
UIViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:#"done"];
[self.navigationController pushViewController:controller animated:YES];
}
I've obviously missed something, and i'm guessing it's to do with the application going into the background and the VC being "unloaded" from memory, and needing re-instatiating, but i'm not sure where to begin with that.
Any help would be greatly appreciated as i'm about to throw the computer out of the window . .
Thanks
Gareth
Edit 1
After doing some more troubleshooting it appears that during this call in the VC:
[self dismissViewControllerAnimated:NO completion:nil];
[self.navigationController popToRootViewControllerAnimated:NO];
self.navigationController is nil . . .
I'm guessing that is likely the cause of the issues i'm seeing?
Edit 2
So as suggested by Kelin, i am trying to make sure i retain the Navigation Controller.
I have done the following in AppDelegte:
#property (nonatomic, strong) UINavigationController *navController;
and
#synthesize navController;
But when i try to access this from the VC using the below code, it's still nil . .
AppDelegate *appDelegate = [[UIApplication sharedApplication]delegate];
UINavigationController *navController = appDelegate.navController;
[self dismissViewControllerAnimated:NO completion:nil];
[navController popToRootViewControllerAnimated:NO];
Edit 3
I have also added this to the AppDelegate, which means the Navigation Controller is no longer nil. But still nothing happens . . .
if (!self.navController)
{
self.navController = [[UINavigationController alloc]initWithNibName:#"Main" bundle:nil];
}
The problem is you trying to perform segue from storyboard using programmatically created View Controller.
You use -performSegueWithIdentifier: sender: completely wrong. In this method "sender" is a button, or any other control which action initialises segue, but not the view controller to be pushed.
Usually segue is created with storyboard. But if you really need to create it manually, call:
-[UIStoryboardSegue initWithIdentifier:source:destination:]
where source and destination are view controllers.
Read this: https://developer.apple.com/library/ios/recipes/xcode_help-interface_builder/articles-storyboard/StoryboardSegue.html
or this (about custom segues):
You can not do both dismiss and pop together either you have to pop or dismiss the view controller and
Every ViewController have it's own NavigationController which is default point out to navigation controller you added to AppDelegate.
So, You also can access it by self.navigationController (Edit 3)
Also check whether you initialised navigation controller in
AppDelegate
self.navController = [[UINavigationController alloc] initWithRootViewController:firstVC];
My UIViewController stack looks as follows:
+------ UIViewController_C (presented)
+---- UIViewController_B (presented)
+-- UIViewController_A (pushed)
When I call -dismissViewController:animated on UIViewController_C, UINavigationController dismisses both UIViewController_C and UIViewController_B together, as per the docs with animation on _C, and none on _B.
What is the most compliant way to dismiss _C only?
try as below
after pushing to UIViewController_A present UIViewController_B as below code.
UIViewController_B *bbp=[[UIViewController_B alloc]initWithNibName:#"UIViewController_B" bundle:nil];
UINavigationController *passcodeNavigationController = [[UINavigationController alloc] initWithRootViewController:bbp];
passcodeNavigationController.navigationBar.hidden=YES;
[self.navigationController presentModalViewController:passcodeNavigationController animated:YES];
[passcodeNavigationController release];
now from UIViewController_B try to present in UIViewController_C as below code.
UIViewController_C *bbp=[[UIViewController_C alloc]initWithNibName:#"UIViewController_C" bundle:nil];
UINavigationController *passcodeNavigationController = [[UINavigationController alloc] initWithRootViewController:bbp];
passcodeNavigationController.navigationBar.hidden=YES;
[self.navigationController presentModalViewController:passcodeNavigationController animated:YES];
[passcodeNavigationController release];
last and final thing on every back button of view controller write below line of code.
[self dismissModalViewControllerAnimated:YES];
if you want more help than comment bellow.
One Solution:
UIViewControllers presented modally are not necessarily deallocated on -dismissViewController:animated.
This means that by passing a reference to UIViewController_A through _B to _C, you can call -presentViewController:animated and -dismissViewController:animated for the respective UIViewControllers via UIViewController_A.
Code:
1. UIViewController_B
- (void) showUIViewController_C {
[self dismissViewControllerAnimated:TRUE completion:^{
UIViewController_C *controller_C = [[UIViewController_C alloc] init];
controller_C.parentController = self;
[self.parentController controller_C animated:TRUE completion:nil];
}];
}
2. UIViewController_C
- (void) dismissUIViewController_C {
[self dismissViewControllerAnimated:TRUE completion:^{
[self.parentController.parentController presentViewController:self.parentController animated:TRUE completion:nil];
}];
}
Where I am using *parentController as the naming convention for whatever class your previous UIViewController on the stack may be.
It dips back to UIViewController_A briefly because I am calling -dismiss and -present in the completion block, though that actually looks rather fun.
I read a lot of documentation about this before i decided to ask.
So I have navigationController in my app. When user enters the first time in my app I do this
RegViewController *opr = [[RegViewController alloc] init];
self.regController = opr;
[self.navigationController presentModalViewController:self.regController animated:NO];
[opr release];
And it works fine. But when I click OK button in RegViewController I call this method
-(IBAction)btn_regPressed:(id)sender
{
NSLog(#"start to dissmis modal");
[self.navigationController dismissModalViewControllerAnimated:YES];
//[self.navigationController.parentViewController dismissModalViewControllerAnimated:YES];
}
But this code doesn't want to dismissModalViewController
Can somebody help me with thios issue please. Thanks
try to change your call to (remove the navigationController):
[self presentModalViewController:self.regController animated:NO];
and in your button (remove the navigationController):
[self dismissModalViewControllerAnimated:YES];
You are telling to your navigationController dismiss your modal, but your viewcontroller should do it.
Navigation controllers are used to navigation (go and back) purposes. And probably, your navigationController is nil.
In your RegViewController, try to dismiss self like so:
-(IBAction)btn_regPressed:(id)sender
{
NSLog(#"start to dissmis modal");
[self dismissModalViewControllerAnimated:YES];
}