UINavigationController back button not animating - ios

I'm having a weird issue with a navigation controller's back button animation:
my app has a tab bar control with 3 tabs, one of them has a navigation controller with two subsequent view controllers, the first one just show a master table and the second one details, the problem comes when I tap the back button from the detail view controller, instead of slide back to the master view controller it just pops the view without animation.
I've noticed that if I first go to another tab, and then return again to this one, the animation will trigger normally.
I've rebuilt the whole app navigation from scratch but the problem still persist, any help is appreciated.
Thanks in advance!.
Edit: More info added
This is how my storyboard looks like in that particular branch:
Here's the prepareForSegue from "Partidos Activos" view controller:
#pragma mark - Segues
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.identifier isEqualToString:#"PartidosEnDia"]) {
PartidosActivosEnFecha *paf = segue.destinationViewController;
CalendarCell *senderCell = (CalendarCell *)sender;
paf.datos = senderCell.dataDic;
}
}
Both viewController viewDidLoad methods are calling super at the start of the method.
As I told before, if I just tap on other tab and then come back to this one, the slide back animation from "Partidos Activos En Fecha" viewController works as expected, it's only when I start the application and go directly to this viewController when the slide back animation doesn't work, and it just gets to the caller viewController without animation.
Hope I added enough info, if not just tell me and I will add it again.

I finally found where the problem was, I was missing a call to super in the viewDidAppear method but in UITabBarController!, I was checking only viewControllers for the tabs but not the tabbarviewcontroller. #rdelmar was right.

I had the exact same problem. The cause for me was an empty viewDidAppear:animated method in my UITabBarController. Once I deleted that method, the animation worked normally again.

I think this it's what you want. If I understand, your problem is handle the stack of the navigation controller right? So, check that link.

Related

Segue to home view

I am trying to segue back to a home screen and pop everything from the stack (of views?)
I am using UINavigationController:
[self.navigationController popToRootViewControllerAnimated:YES];
Where shall I call this method? I have tried in -(void) prepareForSegue which does not work.
Basically I want to make sure when I go back to home screen there is no back button on the left of the title.
Home screen here refers to the welcome screen of my App.
I am not sure which part of my code shall be posted. Please comment if you need to see my code.
Thank you in advance.
Assuming you're using a Storyboard, and a UIButton declared over there is the one that triggers that action you wanna perform, you should declare an IBAction: -(IBAction)buttonPressed:(id)sender; in the .h and implement it in the .m. Inside that method should appear that [self.navigationController popToRootViewControllerAnimated:YES]; code. Also remember to attach that action to that UIButton when touch up inside in the storyboard.
Hope it helped!
I think your confusion is around the concepts of what a segue is and how it relates to the navigation controller stack. The stack is exactly the same as the basic data structure stack (http://en.m.wikipedia.org/wiki/Stack_(abstract_data_type)) in that it's a last-in-first-out store. When you segue, you're normally adding to that stack, e.g. Pushing a new VC onto the stack. A back button in most cases would not be doing that. It would be popping, or removing from the stack. Which is why you probably wouldn't call pop methods from the prepareForSegue method. Instead try calling it at some other point, like when they tap the back button, or after some action has taken place.

Modal ViewController presenting another viewController won't animate immediately

Yes, I struggled a bit with that title...
Here's what my setup is meant to do:
I push a viewController (resultViewController) onto the navigation stack. Immediately (literally in the next line of code) I present another viewController to the rootViewController (filterViewController).
So far, so good, and things work as expected.
The modally presented viewController contains a tableView. Selecting a cell is supposed to present another viewController in the current (filterView) controller.
[self presentViewController:filterDetailsController animated:YES completion:^(void){
}];
This is where things go awry: The above snippets is called at the correct time, but the viewController does not appear until I perform an additional tap or gesture somewhere in the filterView. This suggest that the stacking of modalView inside modalView somehow messes things up. If I change the animated parameter to NO, the viewController is presented immediately.
An obvious work-around would be to set animated to NO and perform a manual animation in the completion block. I would however love to see if anyone have come across anything similar and knows how to fix the problem.

IOS7 - performSegueWIthIdentifier does not have any effect

I have a problem in iOS7 where I am calling a segue with performSegueWithIdentifier (I have code just like this that works just about everywhere else), then I log the segue in prepareForSegue, then I log again the view controller (VC) that the segue is supposed to push to the top.
prepareForSegue gets called appropriately and the segue has the correct string as its identifier property. Yet the VC that it is supposed to push to the top never gets initialized nor viewWillAppear gets called.
The segue I am talking about, which is the only one that does not work (all the other ones work in both ios6 and 7), is the one leading form the center VC to the right VC. By the way, this works flawlessly in iOS6.
What could be the cause?
the code:
-(IBAction)gotoMainMenu:(id)sender{
DLog(#"DifferentName");
[self performSegueWithIdentifier:#"DifferentName" sender:self];
}
Get in the habit of not wiring up segue's to buttons. Wire them up to the VC and then in the touchUpInside action, fire off the performSegueWithIdentifier.
I had the same issue and solved it as follows. In view A I had a segue that was triggered by a button (UIButton) and the button was also connected to an action in my controller. When I clicked the button in View A, View B would appear as expected. However, when I tried clicking a button in View B to go to View C nothing happened just as you described above.
In my case the issue was resolved in View A. I removed the segue that was tied to the button and let the IBAction that was associated with the button handle calling the performSegueWithIdentifier, then I created a new manual segue that was only tied to the view and voila things worked as expected again.
In short, I guess make sure you don't have both and action and a segue linked to the same button. Hope this helps.

ViewDidLoad Method is called again

I have two View Controller. In the first I do some stuff and then I can push the second View Controller by clicking a button (the button connected with the other ViewController in the storyboard). There I can do some settings and so on. I get back to the first View Controller with the button "Done". But then the ViewDidLoad method is called again and all the "stuff" (text in textfields, ...) is gone.
I hope you guys understand my problem.
Why? And how can I disable this?
How are you going back to the first view controller from the second one? I think your problem is you're re-instantiating the first view controller when the user hits "Done".
Instead, you should be using either "popViewControllerAnimated" or "dismissViewControllerAnimated" to go back to the first view controller.
e.g: (one of these 2 should work):
[self.navigationController popViewControllerAnimated:YES];
[self dismissViewControllerAnimated:YES completion:nil];
Maybe the firstViewController is unLoaded because of receiving memory warning. So when it opened again, it calls ViewDidLoad

Pop the current view using Segues/Storyboard on iOS 5

I am creating an app using iOS 5 SDK. I managed to push views using the Storyboard's Segues, but I cannot find the proper way to pop the current view and go back to the previous one.
I am not using any navigationController (the app doesn't have any top or bottom bars).
I don't think using modal or push segue the other way would be the solution as it instantiates a new controller.
Do I have to use a custom Segue with the opposite animation and deletion of the view at the end ? Or is there a better way ?
Storyboards in iOS 5 don't provide a "no-code" way to return from a segue -- that's something you'll need to implement yourself.
If you use "push" segues (which require a navigation controller), use the navigation controller's popViewControllerAnimated: method to undo the last push segue. (Or other methods to undo more; see the UINavigationController documentation.)
If you use "modal" segues, call dismissViewControllerAnimated:completion: on the view controller which presented the current view controller (which you can get from its presentingViewController property).
Update: In iOS 6 and later there's unwind segues for going "back" in a storyboard. It's still not a no-code solution -- and it shouldn't be, because you need to be able to do things like differentiating between "Done" and "Cancel" exits from a modal view controller. But it does let you put more of the semantic flow of your app into the storyboard. Apple has a tech note that describes them in detail, and they're also covered in the video from WWDC 2012 Session 407.
You could try calling [self dismissViewControllerAnimated:YES completion:nil]; from the controller you want to dismiss (whether the controller has been pushed, or shown modally).
Here is the related documentation : UIViewController Class Reference
The presenting view controller is responsible for dismissing the view controller it presented. If you call this method on the presented view controller itself, it automatically forwards the message to the presenting view controller.
Just to clarify.
In the class that was pushed. Simply wire up the following and the controller and view will be popped off.
[self.navigationController popViewControllerAnimated:YES];
Create Segue type "Custom" on your stroyboard. This can be from a button.
Create a new UIStoryboardSegue class named "popSegue"
In the popSegue.m file add the following;
-(void)perform{
UIViewController *sourceViewContreoller = [self sourceViewController];
[sourceViewContreoller.navigationController popViewControllerAnimated:YES];
}
-In the storyboard editor.
-Select the segue and change the Segue Class to "popSegue"
-Set the Identifier to "popSegue"
Done!
You can use the same "popSegue" class throughout your project.
Hope this helps
I'm using Xcode 5 also and here's how it's done. First, in the view code file that pushed the other, create an IBAction method in the .h file such as this:
- (IBAction)exitToHere:(UIStoryboardPopoverSegue *)segue sender:(id)sender;
Then in the .m file add this:
- (IBAction)exitToHere:(UIStoryboardPopoverSegue *)segue sender:(id)sender {
}
You can add any cleanup code you want executed in this method. Next go to your storyboard and select the pushed view. I assume you've got some kind of button on the view that the user taps to signal he's finished. Click on that button, hold down the key and drag to the the green box below the view which is the Exit. Release the mouse button but continue to hold the key. A popup will appear and your method will show in the list. Select that method. Now when the user clicks on the button, the view will pop and you'll be returned to the starting method.

Resources