Programmatically go back to previous ViewController in Swift

IosSwiftSegue

Ios Problem Overview


I send the user over to a page on a button click. This page is a UITableViewController.

Now if the user taps on a cell, I would like to push him back to the previous page.

I thought about something like self.performSegue("back").... but this seems to be a bad idea.

What is the correct way to do it?

Ios Solutions


Solution 1 - Ios

Swift 3:

If you want to go back to the previous view controller

_ = navigationController?.popViewController(animated: true)

If you want to go back to the root view controller

_ = navigationController?.popToRootViewController(animated: true)

If you are not using a navigation controller then pls use the below code.

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

animation value you can set according to your requirement.

Solution 2 - Ios

Swift 3, Swift 4

if movetoroot { 
    navigationController?.popToRootViewController(animated: true)
} else {
    navigationController?.popViewController(animated: true)
}

navigationController is optional because there might not be one.

Solution 3 - Ios

Swift 3

I might be late in the answer but for swift 3 you can do it this way:

override func viewDidLoad() {
    super.viewDidLoad()
    
    navigationItem.leftBarButtonItem = UIBarButtonItem(title: "< Back", style: .plain, target: self, action: #selector(backAction))
    
    // Do any additional setup if required.
}

func backAction(){
    //print("Back Button Clicked")
    dismiss(animated: true, completion: nil)
}

Solution 4 - Ios

Swift 4

there's two ways to return/back to the previous ViewController :

  1. First case : if you used : self.navigationController?.pushViewController(yourViewController, animated: true) in this case you need to use self.navigationController?.popViewController(animated: true)
  2. Second case : if you used : self.present(yourViewController, animated: true, completion: nil) in this case you need to use self.dismiss(animated: true, completion: nil)

> In the first case , be sure that you embedded your ViewController to a navigationController in your storyboard

Solution 5 - Ios

swift 5 and above

case 1 : using with Navigation controller

self.navigationController?.popViewController(animated: true)

case 2 : using with present view controller

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

Solution 6 - Ios

In the case where you presented a UIViewController from within a UIViewController i.e...

// Main View Controller
self.present(otherViewController, animated: true)

Simply call the dismiss function:

// Other View Controller
self.dismiss(animated: true)

Solution 7 - Ios

If Segue is Kind of 'Show' or 'Push' then You can invoke "popViewController(animated: Bool)" on Instance of UINavigationController. Or if segue is kind of "present" then call "dismiss(animated: Bool, completion: (() -> Void)?)" with instance of UIViewController

Solution 8 - Ios

for swift 3 you just need to write the following line of code

_ = navigationController?.popViewController(animated: true)

Solution 9 - Ios

This one works for me (Swift UI)

struct DetailView: View {
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>

  var body: some View {
      VStack {
        Text("This is the detail view")
        Button(action: {
          self.presentationMode.wrappedValue.dismiss()
        }) {
          Text("Back")
        }
      }
    }
}

Solution 10 - Ios

Try this: for the previous view use this:

navigationController?.popViewController(animated: true)  

pop to root use this code:

navigationController?.popToRootViewController(animated: true) 

Solution 11 - Ios

Swift 4.0 Xcode 10.0 with a TabViewController as last view

If your last ViewController is embebed in a TabViewController the below code will send you to the root...

navigationController?.popToRootViewController(animated: true)
navigationController?.popViewController(animated: true)

But If you really want to go back to the last view (That could be Tab1, Tab2 or Tab3 view..)you have to write the below code:

_ = self.navigationController?.popViewController(animated: true)

This works for me, i was using a view after one of my TabView :)

Solution 12 - Ios

For questions regarding how to embed your viewController to a navigationController in the storyboard:

  1. Open your storyboard where your different viewController are located
  2. Tap the viewController you would like your navigation controller to start from
  3. On the top of Xcode, tap "Editor"
  4. -> Tap embed in
  5. -> Tap "Navigation Controller

Solution 13 - Ios

I would like to suggest another approach to this problem. Instead of using the navigation controller to pop a view controller, use unwind segues. This solution has a few, but really important, advantages:

  1. The origin controller can go back to any other destination controller (not just the previous one) without knowing anything about the destination.
  2. Push and pop segues are defined in storyboard, so no navigation code in your view controllers.

You can find more details in Unwind Segues Step-by-Step. The how to is better explained in the former link, including how to send data back, but here I will make a brief explanation.

  1. Go to the destination (not the origin) view controller and add an unwind segue:
    @IBAction func unwindToContact(_ unwindSegue: UIStoryboardSegue) {
        //let sourceViewController = unwindSegue.source
        // Use data from the view controller which initiated the unwind segue
    }
  1. CTRL drag from the view controller itself to the exit icon in the origin view controller:

Unwind from view controller

  1. Select the unwind function you just created a few moments ago:

Select unwind function

  1. Select the unwind segue and give it a name:

Naming unwind segue

  1. Go to any place of the origin view controller and call the unwind segue:
performSegue(withIdentifier: "unwindToContact", sender: self)

I have found this approach payoffs a lot when your navigation starts to get complicated.

I hope this helps someone.

Solution 14 - Ios

I did it like this

func showAlert() {
    let alert = UIAlertController(title: "Thanks!", message: "We'll get back to you as soon as posible.", preferredStyle: .alert)
    
    alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { action in
        self.dismissView()
    }))
    
    self.present(alert, animated: true)
}

func dismissView() {
    navigationController?.popViewController(animated: true)
    dismiss(animated: true, completion: nil)
}

Solution 15 - Ios

I can redirect to root page by writing code in "viewDidDisappear" of navigated controller,

override func viewDidDisappear(_ animated: Bool) { self.navigationController?.popToRootViewController(animated: true) }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionChristianView Question on Stackoverflow
Solution 1 - IosPraveen Gowda I VView Answer on Stackoverflow
Solution 2 - IosVyacheslavView Answer on Stackoverflow
Solution 3 - IosFullpowerView Answer on Stackoverflow
Solution 4 - IosBraham YoussefView Answer on Stackoverflow
Solution 5 - Iosmidhun pView Answer on Stackoverflow
Solution 6 - Iosspencer.smView Answer on Stackoverflow
Solution 7 - IosPankajView Answer on Stackoverflow
Solution 8 - IosAmr AngryView Answer on Stackoverflow
Solution 9 - IosIgor SamtsevichView Answer on Stackoverflow
Solution 10 - IosAhsanView Answer on Stackoverflow
Solution 11 - IosGabo MCView Answer on Stackoverflow
Solution 12 - IosManveer Singh PandherView Answer on Stackoverflow
Solution 13 - IosXMEView Answer on Stackoverflow
Solution 14 - IosYaroslav SarnitskiyView Answer on Stackoverflow
Solution 15 - IosMaheView Answer on Stackoverflow