以编程方式返回 Swift 中的上一个 ViewController

Programmatically go back to previous ViewController in Swift

我通过单击按钮将用户转到某个页面。此页面是 UITableViewController

现在,如果用户点击某个单元格,我想将他推回到上一页。

我考虑过类似 self.performSegue("back").... 的事情,但这似乎不是个好主意。

正确的做法是什么?

Swift 3:

如果你想回到之前的视图控制器

_ = navigationController?.popViewController(animated: true)

如果你想回到根视图控制器

_ = navigationController?.popToRootViewController(animated: true)

如果您没有使用导航控制器,请使用以下代码。

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

动画值可根据需要设置。

Swift 3, Swift 4

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

navigationController 是可选的,因为可能没有。

Swift 3

我可能回答晚了,但是对于 swift 3 你可以这样做:

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)
}

如果 Segue 是 'Show' 或 'Push' 的类型,那么您可以在 UINavigationController 实例上调用 "popViewController(animated: Bool)"。或者,如果 segue 是一种 "present",则使用 UIViewController

的实例调用 "dismiss(animated: Bool, completion: (() -> Void)?)"

我可以通过在导航控制器的 "viewDidDisappear" 中编写代码重定向到根页面,

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

对于swift 3 您只需要编写以下代码行

_ = navigationController?.popViewController(animated: true)

如果您从 UIViewController 中呈现 UIViewController 即...

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

只需调用dismiss函数:

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

Swift 4

有两种方法可以return/back到之前的ViewController:

  1. 第一种情况:如果你使用过:self.navigationController?.pushViewController(yourViewController, animated: true) 在这种情况下 你需要 才能使用 self.navigationController?.popViewController(animated: true)
  2. 第二种情况:如果你使用了:self.present(yourViewController, animated: true, completion: nil) 在这种情况下你需要才能使用self.dismiss(animated: true, completion: nil)

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

试试这个: 对于之前的视图,使用这个:

navigationController?.popViewController(animated: true)  

pop 到 root 使用此代码:

navigationController?.popToRootViewController(animated: true) 

Swift 4.0 Xcode 10.0 带有 TabViewController 作为最后一个视图

如果您的最后一个 ViewController 嵌入到 TabViewController 中,下面的代码会将您带到根目录...

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

但是如果你真的想回到上一个视图(可能是 Tab1、Tab2 或 Tab3 视图..)你必须写下面的代码:

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

这对我有用,我在我的一个 TabView 之后使用了一个视图 :)

有关如何将 viewController 嵌入故事板中的导航控制器的问题:

  1. 打开您的不同 viewController 所在的故事板
  2. 点击viewController您希望导航控制器从
  3. 开始
  4. 在 Xcode 的顶部,点击 "Editor"
  5. -> 点击嵌入
  6. -> 点击“导航控制器

swift 5岁以上

案例 1:与导航控制器一起使用

self.navigationController?.popViewController(animated: true)

案例 2:与当前视图控制器一起使用

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

这个适合我 (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")
        }
      }
    }
}

我是这样做的

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)
}

我想建议另一种方法来解决这个问题。不要使用导航控制器来弹出视图控制器,而是使用 unwind segues。这个解决方案有一些但非常重要的优点:

  1. 源控制器可以在不知道任何关于目的地的情况下返回到任何其他目标控制器(不仅仅是前一个)。
  2. 推送和弹出 segues 在情节提要中定义,因此您的视图控制器中没有导航代码。

您可以在 Unwind Segues Step-by-Step 中找到更多详细信息。 how to在前面link解释的比较好,包括怎么传回数据,这里我就简单说明一下。

1) 转到目的地(不是原点)视图控制器并添加展开转场:

    @IBAction func unwindToContact(_ unwindSegue: UIStoryboardSegue) {
        //let sourceViewController = unwindSegue.source
        // Use data from the view controller which initiated the unwind segue
    }

2) CTRL从view controller itself拖动到origin view controller中的退出图标:

3) Select 您刚才创建的展开函数:

4) Select unwind segue 并为其命名:

5) 转到origin view controller的任意位置并调用unwind segue:

performSegue(withIdentifier: "unwindToContact", sender: self)

我发现当您的导航开始变得复杂时,这种方法会带来很多好处。

我希望这对某人有所帮助。