Dismiss multiple view controllers at once (iOS 8) - ios

So in my code, I have a Tab Bar controller. When you click one of the tabs, it calls this code to open up a new storyboard (for video capture).
NavController *NC = [[NavController alloc] initWithCaptureInput];
[self presentViewController:NC animated:YES completion:nil];
In this view, he records a video and then the storyboard presents the segue. In that view, the user can preview his video. When he click's a button the storyboard pushes him to the next view.
In that last view, I use to call this in iOS 7 to make the app go back to the initial view (before the current storyboard).
[self.presentingViewController.presentingViewController dismissViewControllerAnimated:YES completion:nil];
This worked fine but in iOS 8, the top view is dismissed, and during the animation, you see the video preview view. Its only when the animation is done that the video preview view is removed (as it should be).
Can anyone tell me how I can have my proper animation where the top view is removed and during the animation you only see the initial view? This could be done if the app was to remove all the views at the same time (animating them at the same time too).

Yes, I've noticed that behavior, too. Unwind segues (as described in Technical Note TN2298) appear to handle this more gracefully.
In the view controller that you want to unwind to, add a method that looks like:
// use whatever name most descriptively captures the functional purpose of the
// view controller that you are unwinding _to_
- (IBAction)unwindToMainMenu:(UIStoryboardSegue*)sender
{
}
Then in the IB scene that you are transitioning from, you can control+drag from the "dismiss" button to the exit outlets control (as shown in that technical note or as shown here or here) and choose your unwind segue. In my casual experimentation, when you perform the unwind segue, it would appear that you do not see the interim views briefly during the transition.

Related

How to reset the Navigation Controller in Xcode 6?

Im working on an App for iOS, thats uses the navigationController to switch betweens views. I'm trying to return from to the root viewcontroller from the third view.
I have succeeded in the Main.Storyboard, with dragging a button from third to root view, but then the NavigationController just continues the stack.
Is it possible to make a command from third view, to return to root ViewController, without the NavigationController Bar showing the "Back" button and keeping track and without reseting any Bools.
If you want to hide the back button from the navigation bar.Then write the code in third view's viewDidLoad or in viewWillAppear-
self.navigationItem.hidesBackButton=YES;
And Now write the code in the body of the action button.Such as-
[self.navigationController popToRootViewControllerAnimated:YES];
Let me know if it works for you.Thank you
You can use the [UINavigationCobtroller popToRootViewControllerAnimated:] to close all the view hierarchy to the first but for the remaining issues you can find plenty of answers on SO.

in ios 7 SKScene after dismissing view controller no response

In the start of a game after initializing first SKScene in root view controller I have menu where 3 button(sknodes) lead to other skscenes and one more button which leads to second view controller. After presenting the second view controller when I want to go back to first scene I use dismiss view controller, the root view controller with first scene appears and first scene is frozen.
If you click on the button that leads to some of the first 3 scenes then a new scene presents itself, but under the first scene. I cannot see it, but I can hear the sound of other scenes.
This is happening on devices on ios7; on ios8 it works like charm, the scene is not freezing. I present view controller like this
[self.view.window.rootViewController presentViewController:secondviewcontroller animated:NO completion:nil];
and dismiss
[self dismissViewControllerAnimated:NO completion:nil];
I tried with delegates, segue its same result, every possible solution here.

Bypass UIView without showing

I am using Storyboards for an iOS 7 App. The root controller is a menu. For almost every view, I have a Menu button which brings the App back to that menu using [self.navigationController popToRootController:TRUE]. However, there are two UIView elements where I would like to clear the Navigation Controller view list (as happens when you pop back to the root controller), but then immediately go to another UIView without having the user see the root controller's view. Once at this new view, if the user presses the back button, I want them to go to the menu view.
I've tried to put a performSegue in the viewWillAppear, but it really messes up the Navigation Controller and views. I've tried putting a performSegue in the viewDidAppear, but the user sees first the Menu view flash in, then out on it's way to the correct view.
I hope I've explained this well enough. I hope this can be done.
Thanks.
Your best bet is to build the navigation controller stack yourself, and then use - (void)setViewControllers:(NSArray *)viewControllers animated:(BOOL)animated: to replace the current stack.
So you could do something like
...
UIViewController *vcToPush = ...;
NSArray *newVCStack = #[[self.navigationController.viewControllers firstObject], vcToPush];
[self.navigationController setViewControllers:newVCStack animated:YES];
This will add your new controller to the stack using the standard push animation (or not if you so choose), and after the animation is complete, set the view stack to that of the array.

how to add Back button to go back to previous MonoTouch storyboard view?

In my Xamarin Studio C# MonoTouch storyboard, I have several views and each one has a button to do a modal seque to common view call "ultrasound".
How do I add a Back button to Ultrasound view that will go back to previous view?
I sequed each view by modal to the Ultrasound view.
I added the Ultrasound Back button wired to method button_ultrasound_back, but nothing happens:
Ultrasound_Controller.m
- (IBAction)button_ultrasound_back:(id)sender {
[self.navigationController popViewControllerAnimated:YES];
}
When I try moving the popViewControllerAnimated line into Ultrasound_Controller.cs, then the "self" causes an error.
And, if I change the seques from other view to Ultrasound view from modal to push, then Ultrasound view crashes app.
You need to use the push segue as apposed to a modal. Push requires you to have a UINavigationController and you first view set as its initial view controller. Once you have done this back buttons happen for free, no need to code them yourself.
This is a good intro into Storyboards. It is Obj-C but easy to follow.

Swap/ Transitioning between views iOS programming

I am a newbie to IOS programming and currently i have a tab bar application with two tabs. I have two questions.
The first tab shows a map, imagine it with some pushpins. There is a button on the navigation bar and when this is clicked i want the map view to to move out and a list view to come in. You can see the UI from the image. The button is called list.
Now when i click list I want this view to go away and the list view to come in. So here are my questions ?
1) How do i do this ? I tried the navigation model but i don't want that because I do not want a back button. I tried to make two different views and just dragged the button to that view but the app crashes. I just want the list button on the nab bar and when clicked the view changes to the list view and the button text changes to map. So now if I click the button again it should go back to the map view and the button changes to list.
2) How do i achieve the animations for this ? Ive seen some app where the page flips around and I've seen some options like reducing the opacity etc but I want to achieve the flip animation.
Thank You for any help I get. I really appreciate it.
Interface Builder can do most of this. Hold down the control key and drag from your map View Controller's UIBarButtonItem titled "List" to your list View Controller, then choose the Action Segue "modal". An arrow appears representing the segue; click on it and use the Attributes Inspector to change the Transition to "Flip Horizontal". Here's a video
Or, you could do this programmatically with presentViewController:animated:completion.
Now to get back to the map from the list, I believe that must be done programatically. Create a method that calls dismissViewControllerAnimated:completion: and make your list View Controller's UIBarButtonItem titled "Map" trigger it.
After reading your comments, I am wondering... if the structure of your app is logically a tabbed app structure (as indeed you refer to it as a 'tab bar application'), shouldn't you consider using the UITabViewController instead of a NavigationController? That is what it is designed to do, after all.
If you do use a TabViewController you should reconsider your desire for flip animation, as that doesn't really make UI-sense for tabs. If you can dispense with the flip animation, TabViewController could be a good way to go and you should at least experiment with that before dismissing the idea. It is also designed to grow... you can incorporate any number of tabs in a tab bar. Check out the apple docs (with pictures!)
You will notice that tabs are at the foot of the screen, whereas your 'tab' navController buttons are in a navbar at the top of the screen. This also helps as your app grows, as it is straightforward - from a UI design point of view and programmatically - to incorporate navControllers as navigation tools within individual tabs. For example, if your map/list flip routine does indeed make sense for this part of you app, you can keep this as a single tab (in it's own navigationController) and add other tabs for other parts of the app...
update
From your comment, you are saying that you are interested in the navController-inside-tabBarController setup. In this case here are some ways to get flip transitions AND no back button..
(1) modal presentation
The easiest way to get what you want is to set up one of your viewControllers (say the map view) to present the other one (the list view) modally.
If in the storyboard:
embed your mapViewController in a navController with a navbar button for navigation to the listView as in your picture
add your listViewController to the storyboard and embed it in it's own navContoller (not the mapViewController's navController). Drag a barButtonItem to this navController and wire it up to an IBAction in listViewController
CTRL-drag from mapViewController's 'list' button to the listViewController to create a segue. Select the segue and in the attributes inspector set the segue type to 'modal', with transition 'flips horizontal' and 'animated' checked. Give it a name in case you want to refer to it in code.
in the listViewController's IBAction add this:
[[self presentingViewController] dismissViewControllerAnimated:YES completion:nil];
That should achieve your result. You can use the completion block to send information back from the list view to the map view, and/or set the map view as the listView's delegate.
If you are not using the storyboard check this apple guide
Presenting View Controllers from Other View Controllers
especially "Presenting a View Controller and Choosing a Transition Style".
There is one catch with this approach - when the presented view flips onto the screen, the entire previous view, including the tab bar, is flipped out of the way. The idea is that this is a modal view which the user is required to dismiss before doing anything else in the app.
(2) push/pop in a single navController If this does not suit your intent, you can navigate using a single NavigationController with push and popping of views, and you can hide the back button ... but you really would need to keep the back button functionality as you do want to go back to the mapView, not on to a new map view.
To hide the back button try:
self.navigationItem.hidesBackButton = YES
in the uppermost viewControllers' viewDidLoad
Then you can add a barButtonItem in the xib/storyboard, with this kind of IBAction:
[self popViewControllerAnimated:NO]
or
[self popToRootViewControllerAnimated:NO]
You would have to construct the flip animation in code as it is not supported as a built-in with UINavigationController (best left as an exercise for the reader!)
(3) swapping views in a single viewController As ghettopia has suggested, you could use a single viewController inside a navController (or with a manually place navBar) and swap two views around using the UIView class methods
transitionFromView:toView:duration:options:animations:completion
transitionWithView:duration:options:animations:completion.
This could be a good simplifying solution as your list and map are essentially two views of the same data model.

Resources