0

Basically I have tab bar controller with two tabs, each holds a separate navigation controller, each with a couple of views (see below).

enter image description here

In the "top" navigation controller (held in the right tab), I can choose an image, and then am taken to the rightmost screen to preview the image...

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    if let image = info[UIImagePickerControllerEditedImage] as? UIImage {

        let previewController = self.storyboard?.instantiateViewController(withIdentifier: "previewVC") as! PreviewViewController
        previewController.img = image
        previewController.navigationItem.setHidesBackButton(true, animated: false)
        self.navigationController?.pushViewController(previewController, animated: true)

        self.dismiss(animated: true, completion: nil)
    }
}

...where I tap "post". This uploads the image and calls self.tabBarController?.selectedIndex = 0

That simply takes me to the image feed, which is in the "bottom" navigation controller (left tab). So far so good. However, the preview screen is still displayed in the "right" tab, when I need the upload screen to be displayed after I post.

If I call self.dismiss(animated: true, completion: nil) when I tap post, the entire navigation controller is dismissed and I'm taken back to the login screen.

So I'm trying to dismiss the preview controller so the upload controller is shown as the default view in the right tab, without dismissing the entire stack in that navigation controller.

How can I do this?

KingTim
  • 1,281
  • 4
  • 21
  • 29
  • Not exactly following your navigation structure, but I have provided a couple answers that may solve your issue. Let me know if I am or am not on the right track. – Taylor M Mar 19 '17 at 17:12

2 Answers2

2

If you use navigation controllers to add view controllers to the navigation stack (push), you can remove them by calling a pop function. When you present view controllers modally, you call dismiss to remove the view controller.

Taylor M
  • 1,855
  • 1
  • 14
  • 20
  • The problem is, if I call `self.navigationController?.popViewController(animated: true)` in the upload function, it does indeed bring the upload controller back into the screen, however the upload controller has a `viewWillAppear` which checks if the device has a camera or not, and if it doesn't it goes straight to the image picker. – KingTim Mar 19 '17 at 17:11
  • So in this case, the moment the preview controller is popped out of the view, the picker is re-presented. I need to get back to the feed in the other tab, without showing the upload controller again - although at the same time I need the upload controller to take its place as the default view in the second tab. – KingTim Mar 19 '17 at 17:11
  • Don't present the image picker in view will appear. Maybe move it to view did load so it only gets called once. – Taylor M Mar 19 '17 at 17:13
  • So I ended up putting the pop in the upload function just before `self.tabBarController?.selectedIndex = 0`. It's a little messy but it works - I get taken back to the feed after posting, then if I go back to the right tab, I see the preview controller slide away and show the correct (upload) controller. Thanks for the tip about putting the camera check in `viewDidLoad`. That takes care of the immediate problem of the picker getting in the way when trying to get back to the feed, but I do actually want the picker to present itself each and every time that screen is shown if there is no camera. – KingTim Mar 19 '17 at 17:22
  • Just not while I'm trying to dismiss the preview controller and getting back to the feed. – KingTim Mar 19 '17 at 17:22
  • You could put a check in the delegate function as well. if an image was selected, don't present that the image picker again. – Taylor M Mar 19 '17 at 17:33
  • You mean keep the `viewWillAppear` camera check like I had it, but add something to the `didFinishPickingMediaWithInfo` function? Not sure how I can say in code "don't present the picker again" though. – KingTim Mar 20 '17 at 12:56
0

The delegate function gives you the (image picker) view controller and you should dismiss that, not the view controller that is the delegate (usually the presenting view controller). Maybe try something like this:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    if let image = info[UIImagePickerControllerEditedImage] as? UIImage {

        let previewController = self.storyboard?.instantiateViewController(withIdentifier: "previewVC") as! PreviewViewController
        previewController.img = image
        previewController.navigationItem.setHidesBackButton(true, animated: false)
        self.navigationController?.pushViewController(previewController, animated: true)

        picker.dismiss(animated: true, completion: nil)
    }
}
Taylor M
  • 1,855
  • 1
  • 14
  • 20