View over view breaks hierarchical - ios

I'm using MZFormSheetPresentationController to show as "pop-up" a ViewController2 (embedded in a Navigation controller as suggested) over a ViewController1.
My ViewController1 has a searchbar, a UISegmentedControl and a tableview:
When user clicks on the searchbar bookmark button, pop-up is shown.
I'd like to close the pop-up when user clicks on the done button and it works great using self.dismissViewControllerAnimated(true, completion: nil) method but I'm looking for more. I'd like to present again ViewController1 so tableView will reload data.
I tried with:
self.dismissViewControllerAnimated(true, completion: nil)
print("Dismissed")
//goToTickets
let next = self.storyboard?.instantiateViewControllerWithIdentifier("myTabBar") as! UITabBarController
self.presentViewController(next, animated: true, completion: nil)
but I get this error:
Warning: Attempt to present on whose view is not in the window hierarchy!
Pop-up disappears but I can't present ViewController.
How can I do?
Thanks in advance.
Edit
This is my ViewController2 with identifier "navigationFilter"
and my tabBar:

When you are in the middle of dismissing you are trying to present next ViewController, you have to wait for completion handler and then present next view controller like this:
self.dismissViewControllerAnimated(true, completion: {
let next = self.storyboard?.instantiateViewControllerWithIdentifier("myTabBar") as! UITabBarController
self.presentViewController(next, animated: true, completion: nil)
})

Related

How to dismiss a viewController to rootViewController without showing any VCs in between dismiss process?

Let say I have the following VCs:
RootVC --> VC A --> VC B
I'm using present method to present view controller from RootVC to VC A then to VC B. Now I'm on VC B and I want to dismiss from VC B back to RootVC using
self.view.window!.rootViewController?.dismiss(animated: true, completion: nil)
it works but I still see VC A shows up during the dismiss process. Then, I try this method
self.presentationController?.presentedViewController.dismiss(animated: true, completion: nil)
It also works to dismiss back to root VC but I still see VC A in process.
My question is is there a way to not show VC A during the dismiss process? I already try animated: false but still get the same result. Thanks!
You need to make the change in the modalPresentationStyle to the .custom. The custom will allow you to view the presentingViewController view when the current visible controller's view is transparent.
Now when you want to go back to root view on the current presenting stack you need to call the method dismissToRootViewController(animated: completion:).
In the implementation of this method will allow all intermediate presenting view controller view to be transparent which will give you dismiss animation from VC c to RootVC.
extension UIViewController {
func dismissToRootViewController(animated: Bool, completion: (() -> Swift.Void)? = nil) {
var viewController = self.presentingViewController
while viewController?.presentingViewController != nil {
viewController?.view.alpha = 0.0
viewController = viewController?.presentingViewController
}
self.dismiss(animated: true) {
viewController?.dismiss(animated: false, completion: completion)
}
}
}
You can try to use this:
navigationController?.popToRootViewController(animated: false)

Swift : present a ViewController while alert is shown

I have a problem with present UIViewController Modaly by above code
self.presentViewController(view, animated: true, completion: nil);
it doesn't work when another view present modaly such as UIAlert,its triggered by a socket packet in background and user may is performing another work and may another modal view already presented when the trigger happens.
You can not present two view controllers at the same time from the same source controller. Instead, try presenting the second view controller from the first one that was presented.
if let presented = self.presentedViewController {
presented.present(vcToPresent, animated: true, completion: nil)
}
else {
self.present(vcToPresent, animated: true, completion: nil)
}

iOS - How to not present model view if it is presenting?

I have a floating button to present a model view. I call presentViewController in AppDelegate
UIApplication.sharedApplication().keyWindow?.rootViewController!.getTopViewController().presentViewController(myViewController, animated: false, completion: nil)
When myViewController is presenting, I click my floating button again and my application will call myViewController one more time. So how to not present if it presenting?
What you can do is add a check on your button to check whether the present controller is presenting something which can be done like this
let controller = UIApplication.sharedApplication().keyWindow?.rootViewController!.getTopViewController()
if controller.presentedViewController == nil {
controller.presentViewController(myViewController, animated: false, completion: nil)
}

Using Tab Bar Controller and Navigation Controller

I want to navigate between view controllers as it is shown. I do not want to use segues.
When I try to navigate form FirstViewController to SecondViewController by clicking a button:
let next = self.storyboard?.instantiateViewControllerWithIdentifier("secondViewController") as! SecondViewController
self.presentViewController(next, animated: true, completion: nil)
I get:
Warning: Attempt to present SecondViewController on FirstViewController whose view is not in the window hierarchy!
Any ideas how to insert Navigation Controllers in-between?
Edit: It is TabBarController not TabViewController on the figure.
I navigate from First Scene's controller named "A-Controller" to First View Controller with :
#IBAction func navigateToFirstViewController(sender: AnyObject) {
let next = self.storyboard?.instantiateViewControllerWithIdentifier("firstViewController") as! FirstViewController
self.presentViewController(next, animated: true, completion: nil)
}
It is not shown on the figure.
If you try to present modal view over TabBarController, then :
let next = self.storyboard?.instantiateViewControllerWithIdentifier("secondViewController") as! UIViewController
self.tabBarController.presentViewController(next, animated: true, completion: nil)
Warning: Attempt to present SecondViewController on FirstViewController whose view is not in the window hierarchy!
Turns out this error meant I have to do the navigation from First View to Second View after my First View appears and is ready.
Putting the navigation lines inside viewDidAppear() function solved the issue.

iOS: Go back to previous view

I have two views like this in Story Board:
[View1] -> [Navigation Controller] -> [View2]
To go from View1(has tableview) to View 2, i do this on click of a row on View1:
self.performSegueWithIdentifier("showmyview2", sender:self)
This works.
Now i have a button on View 2, which when clicked should take me back to previous view i.e View 1.
I tried this:
navigationController!.popViewControllerAnimated(true)
But this does not work. How do i go back to first view?
First Add a navigation controller to your First view1 through storyboard.(Editor->Embed Navigation controller), If navigation is not present.
OR
self.dismissViewControllerAnimated(true, completion: nil);
Call this function and try instead of navigation popviewcontroller
Use this code to present first view in your button action:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("FirstView") as! TableViewController
self.presentViewController(vc, animated: true, completion: nil)
And don't forget to give Id to your First view.
Select your firstView into storyBoard and then click on Identity Inspector and you can assign StoryBoard ID like show into below Image.
self.dismiss(animated: true, completion: nil);
this will work in swift 3

Resources