How to programmatically return to previous view controller without navigation controller - ios

I want to return to the previous/root view controller after a certain method finish running. I have found code that could work but I'm not using a navigation controller. I have tried Programmatically changing View Controllers without Navigation Controller Swift but I am not sure how to code it in obj-c. Please help!
Thanks in advance!

If you have presented your view controller (not embeded in a container) than you can simply call
[self dismissViewControllerAnimated:YES/NO completion:nil];
at the end of your certain method.
This turns out from the View Controller Programming Guide for iOS
To dismiss a presented view controller, call the
dismissViewControllerAnimated:completion: method of the presenting
view controller. You can also call this method on the presented view
controller itself. When you call the method on the presented view
controller, UIKit automatically forwards the request to the presenting
view controller.

Related

Dismiss all modals in iOS with Swift 4

I am trying to achieve a navigation similar to the Netflix app for iOS. When you click on a movie, a modal window pops up with a close button. If within this movie I choose to see another movie then the second modal pops up and in addition to the close button, a back button appears. I can use the back button to dismiss one by one and the close button to return to the base screen.
I am able to dismiss a single view using
dismiss(animated: true, completion: nil)
but how can I return to the base screen closing all modals at once? Also, is modals the way to go? I chose this because I didn't want the navigation bar on top.
I'm working with Swift 4.2 in Xcode 10.
The way you are dismissing a ViewController is not the correct way. The presenting view controller is responsible for dismissing the view controller. Ideally you have to implement a protocol in your presenting ViewController and , dismiss your modal from your 'presenting' ViewController not 'presented' ViewController.
The reason why your way still works is, when a ViewController calls self.dimiss if there's nothing to dismiss UIKit will delegate it back to its parent. If you implement this correct way, once you dismiss , your presenting viewcontroller will dismiss , hence all the presented viewcontrollers will be dismissed instead of the last one.
From Apple Docs:
The presenting view controller is responsible for dismissing the view controller it presented. If you call this method on the presented view controller itself, UIKit asks the presenting view controller to handle the dismissal.
If you present several view controllers in succession, thus building a stack of presented view controllers, calling this method on a view controller lower in the stack dismisses its immediate child view controller and all view controllers above that child on the stack. When this happens, only the top-most view is dismissed in an animated fashion; any intermediate view controllers are simply removed from the stack. The top-most view is dismissed using its modal transition style, which may differ from the styles used by other view controllers lower in the stack.
If you want to retain a reference to the view controller's presented view controller, get the value in the presentedViewController property before calling this method.
The completion handler is called after the viewDidDisappear(_:) method is called on the presented view controller.
try this
self.navigationController?.viewControllers.removeAll(where: {$0.isModalInPopover})

Who should be the one dismissing the view controller?

I wanted to ask who should be the one dismissing a presented view controller?
Lets say I presented a view controller and on an IBAction in that view controller, I want to dismiss it.
Should I be passing that responsibility to the presenting view controller by creating a delegate method or I should be just calling the dismissViewController:animated: on itself, which inturn anyways asks its presenting view controller to dismiss the presented view controller?
So, I think these are some clear cut cases where the presenting view controller should be the one dismissing the presented view controller
The presented view controller is passing some data back to the presenting view controller.
The presenting view controller wants to do something after the dismissal of the presented view controller.
The presenting view controller to handle how the dismissal is going to happen, does it need some kind of animation
What if the presented view controller first checks if the presenting view controller actually wants to take the responsibility of dismissal by checking the presenting view controller implemented the dismissal delegate method?
Is it really worth putting the complexity of conditional logic here?
And yes, I tried reading it on other forums and questions like
Dismissing a Presented View Controller
Dismissing Modal View Controllers
Present and dismiss modal view controller
view controllers: presentation, dismissal
But couldn't really find the right logical answer.
Read this below link. You will get the idea how animation and presentation take place between viewcontrollers.
https://www.raywenderlich.com/113845/ios-animation-tutorial-custom-view-controller-presentation-transitions

dismiss a modally presented view controller to a different underlying view controller

I have a UIViewController that's embedded in a Navigation View Controller. I then modally present another view controller that shows a countdown. Once the countdown ends, the modal view controller should be dismissed and show a different underlying view controller from the original presenting UIViewController.
Does anyone know how to do this in ios8 with Swift?
There are different ways to approach this. One way is to replace the initial presenting view controller with the desired underlying one when you present the modal view controller.
NSArray * viewControllers = [self.navigationController viewControllers];
[viewControllers replaceObjectAtIndex:viewControllers.count - 1 withObject:replacementController];
Dismissing the modal will simply show the different underlying view controller that was already swapped.
when you do popViewController from stack there is a handler. This will be called at the end of this function so you can pass a block where you can presentViewController or make change to the current one.

iOS View controller's view alpha

Can I reveal the underlying view (or the view at the back of a view controller), by making a view controller's view transparent? I tried and it just fades to black and doesn't reveal anything behind it.
Reason?
EDIT:
Okay, this question needs more context.
I have a view controller. Now I am going to present another view controller(simple presentation of view controller, modally). After the new view controller has been presented, I am making its view transparent with alpha=0. Why does it not reveal the underlying view controller's view?
Will using the iOS 7 Transition API help?
If you present your view controller modally (using presentViewController:animated:completion:) then the presenting view controller's view will be removed removed from the window, therefore you cannot see through your presented view controller to the presenting view controller. You might want to use child view controller: https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/CreatingCustomContainerViewControllers/CreatingCustomContainerViewControllers.html
Alternatively, you can present your view controller inside a new UIWindow.
You cannot see the original view controller because you use -presentViewController:animated:completion: which will hide the presenting view controller after the animation finished.
You can set the modalPresentationStyle to one of UIModalPresentationOverCurrentContext, UIModalPresentationOverFullScreen and UIModalPresentationCustom before you called 'presentViewController:animated:completion' so that the underlying presenting view controller will not be hidden.
If you would like to have the same background image showing below all UIViewController you can add a UIImageView to the [UIApplication sharedApplication].window in the applicationdidfinishlaunching method

How to dismiss a NavigationController in Storyboard?

I've looked everywhere for this, so as a last resort I figured I should ask the question.
I'm using Storyboard in XCode and have a navigation controller as my initial view. The root view of this navigation controller is a table view. In this table view, I have a button in the navigation bar that flips the view horizontally via a modal segue to a navigation controller. The root view of this controller is my map view. Now, when I want to dismiss this map view using [self dismissViewControllerAnimated:YES completion:nil] it doesn't work. It does if I take out the navigation controller. So, I'm guessing the dismissViewController is getting passed to the navigation controller, and not doing anything. I know I could implement a class for the navigation controller to handle the call and pass it on, but I don't want to do that unless absolutely necessary.
So to solve this question:
I need a way to switch between table view to map view using the flip horizontally animation and vice versa.
I need to have a navigation controller in both views, I could either be the same one, or a different one. I can't seem to find a way to use the same one, since any transitions would be pushes which don't do the flip horizontally transition.
Thanks in advance for the help!
Who is self when you call [self dismissViewControllerAnimated:YES completion:nil]?
The receiver of this message needs to be the view controller which presented the modal view controller you want to dismiss. If you call it on the presented view controller, or (in the case of container view controllers like UINavigationController, one of the view controllers it manages), UIKit will try to do the right thing but won't always succeed.
Presuming the self you refer to is the view controller containing the map view, you can get the presentingViewController property to get the object you should call dismissViewControllerAnimated:completion: on. (And if you need to get the navigation controller that's in between, use the navigationController property.)

Resources