How can to go back to previous view programmatically without UINavigationController? - ios

How can to go back to previous view programmatically without UINavigationController, because all examples that I have found use UINavigationController ?
I am making view for sending feedback and I would like to use this view in many more apps.
If I use UINavigationController than app need to have UINavigationController to use my view for sending feedback.
Is this possible to do and how ?
This is code how I show my view for sending feedback:
- (IBAction)showFeedbackView:(id)sender {
WOC_FeedbackViewController *feedbackView = [[WOC_FeedbackViewController alloc] init];
[self presentViewController:feedbackView animated:YES completion:nil];
}

Use this to go back
[self dismissViewControllerAnimated:YES completion:nil];

Depending on what your project works (Storyboards or XIB) you can use presentViewController. But thats when you keep a reference on your last viewController's identifier.
If you know the ID of your viewController NSString *yourID;
1) Init your viewController
For storyboard
UIViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:yourID];
For XIB
UIViewController *vc = [UIViewController alloc]initWithNibName:yourID bundle:nil];
2) Presenting your ViewController
[self presentViewController:vc animated:YES completion:nil];
P.S This is a way to do this, but you should use navigationController because you can keep memory of a viewController on stack so when you need to access it again, you can access it faster. In other words, UINavigationController is applied in every iOS Application you see on App Store.

In Swift, you can use following line of code to go back to previous view controller without navigation controller:
self.dismissViewControllerAnimated(true, completion: nil)

Related

iOS - Display a UIViewController as fullscreen from within a UINavigationController

I need to present a UIViewController as fullscreen (Above all other views). This UIViewController is currently inside a UINavigationController.
Is it possible to have the UINavigationController present it's current top UIViewController modally?
From within the UIViewController I would like to fullscreen, if I use:
[self.navigationController presentViewController:self animated:YES completion:nil]
Nothing seems to happen.. Is there a reason this is not allowed?
EDIT
I have posted another question in which I have solved this issue for every scenario. (Code snippet included there)
Is it possible for a UIViewController to present itself?
If you want to present a view controller modally, you should be presenting it from a different view controller. The modal presentation will show the presented view controller over the navigation controller (in fullscreen)
For instance,
UIViewController *firstVC = self;
UIViewController *secondVC = <the VC you want to present>
[firstVC presentViewController:secondVC animated:YES completion:nil]
Or just use a modal segue in Interface Builder.
You should use this :
[self presentViewController:self.navigationController animated:YES completion:nil];
to show a controller.
Assuming that the view controller you want to show modally is the navigation controllers top view controller
[self presentViewController:self.navigationController.topviewcontroller animated:YES completion:nil];
Hope this helps

Pop THE RootViewController

I am developing an app that as first viewcontroller has an UIViewController.
This controller pushes a NavigationViewController that contains other controllers.
Now I need to pop the RootViewController of the NavigationController to go back to the initial UIViewController.
I tried with
[self dismissViewControllerAnimated:YES completion:nil];
and the app crashes("Tread1:EXC_BAD_ACCESS(code=1, address= ......)").
I tried with
[self.navigationController popViewControllerAnimated:YES];
and nothing happens.
The initial UIViewController calls
[self performSegueWithIdentifier:#"MyIdentifier" sender:self];
In the UIBuilder the segue is of type "Show(e.g. Push)"
Then I have a NavigationViewcontroller that contains the RootViewController and another Viewcontroller.
What I am trying to achieve is to go back to the first viewcontroller (the one outside the navigationcontroller) from the RootViewController. So I should have the navigationcontroller there.
What am I missing?
Apparently I had a couple of GestureRecognizer still in place that were causing the crash of the app.
The right method was:
[self dismissViewControllerAnimated:YES completion:nil];

How do I present a ViewController over another with that VC having no knowledge of the new one?

I had a method to do this, but it stopped working at some point.
The motivation here is for debugging. I have a button that shows a debugging action sheet from whatever VC calls it. This works great. However, in the action sheet, after I select one, the action wanted is in some cases the presentation of a new VC. The first example of this was a VC that displays my internal log. It's very valuable when not debugging in a "tethered" mode.
Each debugging VC is represented as a scene in the Main storyboard. I instantiate the VC with instantiateViewControllerWithIdentifier:. Then I am trying to get it presented.
The tricky part is that the new VC has to be presented and then dismissed without writing any code in the VC that is currently active. Neither do I want to create a Segue from every VC where this might be called. The whole point is that the DebugActionSheet is self contained except for the single call to fire it up.
You should be able to access the top most view controller like this from your ActionSheet delegate method.
+ (UIViewController*) topMostController
{
UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;
while (topController.presentedViewController) {
topController = topController.presentedViewController;
}
return topController;
}
then in the calling code:
[MyDebugController.topMostController presentViewController:myLoggingView
animated:YES
completion:nil];
and your myLoggingView can dismiss itself by calling
[self.presentingViewController dismissViewControllerAnimated:YES
completion:nil]
Try presenting it on the main thread?
dispatch_async(dispatch_get_main_queue(), ^ {
[self presentViewController:vc animated:YES completion:nil];
});
It turned out my problem was that the current top controller is using a Navigation controller, so the required code is different.
UIStoryboard *story = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
_paletteVC = [story instantiateViewControllerWithIdentifier:#"PaletteDisplayVC"];
[[_delegate navigationController] pushViewController: _paletteVC
animated: YES];
I pass the current top controller to my DebugActionSheet as delegate, so I do not need the topMostController method above. However, I presume it would work with that also.

How to create ViewController in my situation? ios7

I got first ViewController with out navigation controller, I go from it to second ViewController via
if (!self.mapViewController)
{
self.mapViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"MapViewController"];
}
[self presentViewController:self.mapViewController animated:YES completion:nil];
I send some data with prepareForSegue to it, but I need that it also be with navigation controller.
I embed in a navigation controller in storyboard but my code still called second ViewController with out navigation.
I am not a professional with the way of the storyboard, however i believe that instead of presentViewController
you should be using the following function to present a storyboard VC based on segues.
[self performSegueWithIdentifier:#"SegueIdentifierHere" sender:nil];
Make sure that in your storyboard you have incorporated a UINavigationControllerVC as well.
Give an identifier to the navigation controller in storyboard. Instantiate and present that.
UINavigationController *navVC = [self.storyboard
instantiateViewControllerWithIdentifier:#"TheNavVCWhoseRootIsMyMapViewController"];
self.mapViewController = navVC.viewControllers[0]; // your map vc is at the root
[self presentViewController:navVC animated:YES completion:nil];
You are using presentViewController:animated:completion which will indeed display a UIViewController without the UINavigationController the previous UIViewController was embedded in.
Try using the following:
[self.navigationController pushViewController:self.mapViewController animated:YES]

Memory management - How to show an already instantiated ViewController without creating a new instance

I am having major memory management issues. After small use of the program it will crash running out of memory. I have finally found the cause, every time I create a new ViewController rather than accessing the instance, I am creating a new instance.
So app loads and instantiates the FirstViewController. You click a button which instantiates FilterViewController. From here when going back to FirstViewController I am creating a new instance of this as follows:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName
:#"MainStoryboard" bundle:nil];
FirstViewController *fvc = [storyboard
instantiateViewControllerWithIdentifier:#"FirstViewController"];
fvc.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
And repeat process. Any way of presenting the view controller without re-instantiating it? I am close to submitting the app (tomorrow hopefully) so I need to try get this sorted. Thanks!
Here is the presentation of the ViewController.
[self presentViewController:fvc animated:YES completion:nil];
Presenting FilterViewController from FirstViewController
- (IBAction)searchOptions:(id)sender {
FilterViewController *ctrl = [[FilterViewController alloc] init];
[UIView transitionFromView:self.view toView:ctrl.view duration:1 options:UIViewAnimationOptionTransitionCurlUp completion:nil];
self.filterViewController = ctrl;
[self.navigationController pushViewController:self.filterViewController animated:NO];
}
If you're using presentViewController, you get back to the previous view by calling [self dismissViewControllerAnimated:YES];. You would do that in the method where you're currently creating the new controller.
If you are pushing into a navigation controller you would pop from the navigation controller: [self.navigationController popViewControllerAnimated:YES];.
Based on your last update it seems like you don't have a navigation controller and you're just adding the view as a subview and storing the filter view controller. That makes life more complicated really and the correct way to remove it is to setup a delegate relationship so that the filter view controller calls back to the first view controller when it's done and the first controller then transitions the views and nil's the reference.
If you can, change to use a navigation controller properly. You already have half the code, but the first view controller seems to not be in a navigation controller. If you use a nav controller life will be easy...

Resources