In the first screenshot, LatestPost is set as Is Initial View Controller. When I press Camera tab, it launches the .Camera for UIImagePickerController. However when I hit "Cancel", it dismisses the current ViewController, and my tab bar goes missing as shown on the second screenshot.
The second screenshot is embedded inside a UINavigationController.
I quite certain that has got to do with dismissing my ViewController. The question here is how do I "de-initialized" my ViewController?
My codes as follow:
func imagePickerControllerDidCancel(picker: UIImagePickerController) {
dismissViewControllerAnimated(true, completion: nil)
}
EDIT: Added Storyboard screenshot as requested.
Related
In the delegate of UIImagePickerController when an image is taken with the camera, another view is pushed onto the navigation stack:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
picker.pushViewController(otherViewController, animated: true)
}
In the otherViewController the navigation bar is made visible:
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.setNavigationBarHidden(false, animated: false)
}
When the < Back button in the navigation bar is tapped, the navigation bar becomes invisible again, the camera view appears, but the camera image is frozen and tapping the bottom bar buttons has no effect.
Why is that?
A workaround is not to offer the user to navigate back by replacing the Back button with a Cancel button. That dismisses the UIImagePickerController and automatically dismisses all higher views on the navigation stack, including the otherViewController.
// Replace `Back` button with `Cancel` button in the `otherViewController`
navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(self.cancelButtonTapped))
#objc func cancelButtonTapped() {
// Dismiss the `UINavigationController`, e.g. by calling a delegate function
// ...
}
As a result the user would have to start the process again from the beginning instead of just navigating back.
You are directly pushing A new view before dismissing picker you had presented this is why when you come back your camera image picker is still on stack as its not dismissed
dismiss(animated:true, completion: nil)
after this push your new View as you want. didFInish is used to get the result and dismiss the picker you used pass image selected or clicked to new controller if required but dismissing to picker is required
I'm trying to do the following:
User presses button
UIImagePickerController pops up
User selects image
UIImagePickerController is dismissed
Segue into another ViewController
As of now, I have it set up that when the user presses a button, a UIImagePickerController is initialized and presented with presentViewController. It is also delegated to the class that this button is linked to as well. After the user picks an image, imagePickerController is called, and dismissViewControllerAnimated is also called. Then, performSegueWithIdentifier is called. However, this last step throws the following warning, and then does not segue:
2016-09-15 03:45:44.870 Food Diary[9941:1540144] Warning: Attempt to present
on whose view is not in the window hierarchy!
I am very new to Swift and iOS development, what does this mean and how do I fix it?
Perform segue on completion of dismiss of UIImagePickerController
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
// your code
self.dismissViewControllerAnimated(true, completion: {
self.performSegueWithIdentifier("SegueIdentifier", sender: self)
})
}
Note: With sender I have passed current Controller object you can any object that you want.
Try to using these two lines code during presenting and dissmising your view controller
Presenting :
self.view.window.rootviewcontroller.presentViewController("yourVC",animated:true, nil)
Dissmising :
self.view.window.rootViewController.dismissViewController(animated:true completion:nil)
It stays on the same ViewController because the UIImagePickerController is still in view hierarchy a the d second ViewController cannot be added on top of UIImagePickerController. To fix, you need to wrap your segue in the completion of UIImagePickerCopntroller dismissal like this:
self.dismiss(animated: true, completion: {
self.performSegue(withIdentifier: "StartToMain", sender: nil)
})
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)
})
My first view controller has a button, which triggers the #IBAction goTo2ndVc() which presents a second ViewController:
class FirstVC: UIViewController {
...
#IBAction func goTo2ndVc() {
let secondVc = SecondVC(label: "I am second vc.")
self.presentViewController(secondVc, animated: true, completion: nil)
}
When the button is pressed, the 2nd view controller is shown on screen. No problem.
In 2nd view controller, there is also a button which is used to go back to 1st view controller:
class SecondVC: UIViewController {
...
#IBAction func backToFirst(sender: AnyObject) {
print("go back ...")
self.navigationController?.popViewControllerAnimated(true)
}
}
I looked on internet, people suggest to use navigationController?.popViewControllerAnimated(true) to go back to previous controller. But when I press the go back button I can see the print message "go back ..." but the app doesn't go back to 1st view controller. WHY?
#IBAction func backToFirst(sender: AnyObject) {
print("go back ...")
self.dismissViewControllerAnimated(true, completion: nil)
}
In Swift 3
self.dismiss(animated: true, completion: nil)
you should not use navigation controller, because you didn't use it when you were adding the second view controller. that's why simply call dismissViewControllerAnimated method.
You have to use UINavigationController and its pop methods only when you add your view controllers via pushViewController method.
Familiarize yourself with the concept of navigation controller here: https://developer.apple.com/library/ios/documentation/WindowsViews/Conceptual/ViewControllerCatalog/Chapters/NavigationControllers.html
there
the issue is very simple..
self.presentViewController(secondVc, animated: true, completion: nil)
the code will present second view, you are not pushing it.
self.navigationController?.popViewControllerAnimated(true)
the popViewController will pop back to the previous view controller from where it is been pushed.
So, there are two ways you can achieve what you want
1)If you want to present viewController then you have to dismiss the view controller to show previous view controller with
self.dismissViewControllerAnimated(true, completion: nil)
2)If you want to use PopToVewcontroller, then you have to push you second view controller instead of presenting it with
self.navigatioVonroller?.pushViewController(secondVc, animated: true)
If you want to return to the previous view controller, you can simply add:
[self dismissViewControllerAnimated:YES completion:nil];
to the button action method.
If this is added on the nav view controller present on every screen, I see no reason why it shouldn't work as it would always dismiss the most recently presented view.
I am receiving this error after dismissing a multipeer connectivity window:
"Warning: Attempt to present < AudioWaves.ViewControllerJoin: 0x176cf2d0> on < AudioWaves.ViewController: 0x17594de0> whose view is not in the window hierarchy!"
Here is my code below,
func browserViewControllerDidFinish(
browserViewController: MCBrowserViewController!) {
// Called when the browser view controller is dismissed (ie the Done
// button was tapped)
let ViewControllerjoin:ViewControllerJoin = ViewControllerJoin()
self.presentViewController(ViewControllerjoin, animated: true, completion: nil)
dismissViewControllerAnimated(true, completion: nil)
}
If I put the dismiss before the presenting of the new view controller the browser dismisses however the app simply brings to a blank black screen with no error.
Chain your two calls like this:
dismissViewControllerAnimated(true, completion: {
self.presentViewController(ViewControllerjoin, animated: true, completion: nil)
})
This way chains first the dismissViewControllerAnimated and then the presentViewController, this prevent your hierarchy from strange behavior
This helped the asker to verify that his ViewController indeed is the black screen: Try changing the background color of the ViewControllerJoin to blue for example and trying again, once I saw that the default backgroundColor caused a black screen in a ViewController (this seems to help the