【问题标题】:Programmatically go back to previous ViewController in Swift在 Swift 中以编程方式返回到以前的 ViewController
【发布时间】:2015-04-29 21:32:47
【问题描述】:

我通过单击按钮将用户发送到页面。这个页面是一个UITableViewController。

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

我想过像self.performSegue("back").... 这样的东西,但这似乎是个坏主意。

正确的做法是什么?

【问题讨论】:

  • self.navigationController?.popViewControllerAnimated(true)

标签: ios swift segue


【解决方案1】:

斯威夫特 3:

如果你想回到上一个视图控制器

_ = navigationController?.popViewController(animated: true)

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

_ = navigationController?.popToRootViewController(animated: true)

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

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

动画值可以根据自己的需要设置。

【讨论】:

  • 点击单元格时如何将数据发送回previousController?如果我们使用的是 navigationController?.popViewControllerAnimated(true)
  • @JDDelgado 这就是您将数据发回给用户的方式,stackoverflow.com/questions/12561735/…
  • 对于 Swift 3,它是 .popViewController(animated: true)
  • 关闭任何警告:_ = self.navigationController?.popToRootViewController(animated: true)
  • 我们忽略了返回值; _ = 是 swift 的约定。
【解决方案2】:

斯威夫特 3、斯威夫特 4

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

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

【讨论】:

  • @Vyacheslva 我收到一个错误“在闭包中隐式使用'seft',使用'self'使捕获语义显式”
  • @SandipSubedi 使用 [weak self] 和 self?.navigationController?.
  • 这很有用但我想通过导航发送一些变量但现在我不能 - 我使用了override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if let vc = segue.destination as? 但是当我使用这个时我不能使用那个
  • 那么如何添加navigationController呢?
  • @user25 添加?你什么意思?
【解决方案3】:

斯威夫特 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)
}

【讨论】:

  • 这并不“完全”正确。如果您呈现一个包含自己导航的视图控制器,并且在您推送视图控制器后使用该方法dismiss: 它不仅会关闭当前视图控制器,还会关闭根视图控制器,这不是这里所要求的。
  • 问题没有询问用户是否有导航控制器。这是没有导航控制器的最简单和最好的答案。这应该是公认的答案。
  • 谢谢 Droid - 嗨 ernestofndz,你说 rootVC 也将被解散可能是对的,但这不会发生在我身上,它只会解散 currentVC,我正在以编程方式添加和删除项目,并且它可能与故事板上的正常添加元素的方法不同。如果我错了,请纠正我的理解...对于 tableView 如果用户需要将详细信息传递给另一个视图,那么这是另一种情况,与什么没有联系我已经发布并且会 100% 同意你的观点。我的理解是在这种情况下需要一个后退按钮 :)
  • 也许你可以添加一点介绍..因为存在dismiss & navigationController?.popViewController
  • dismiss(animated: true, completion: nil) 旋转后不起作用!
【解决方案4】:

如果 Segue 是“Show”或“Push”的种类,那么您可以在 UINavigationController 的实例上调用“popViewController(animated: Bool)”。或者,如果 segue 是一种“存在”,则使用 UIViewController 实例调用“dismiss(animated: Bool, completion: (() -> Void)?)”

【讨论】:

    【解决方案5】:

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

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

    【讨论】:

    • 这会导致导航控制器弹出到根目录,即使您想在层次结构中向前移动。
    【解决方案6】:

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

    _ = navigationController?.popViewController(animated: true)
    

    【讨论】:

      【解决方案7】:

      如果您从UIViewController 中提交了UIViewController,即...

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

      只需调用dismiss函数:

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

      【讨论】:

      • self.dismiss(animated: true) - 旋转后不起作用
      【解决方案8】:

      斯威夫特 4

      有两种方法可以返回/返回上一个 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)

      在第一种情况下,确保将 ViewController 嵌入到故事板中的 navigationController

      【讨论】:

        【解决方案9】:

        试试这个: 对于上一个视图,请使用:

        navigationController?.popViewController(animated: true)  
        

        pop to root 使用此代码:

        navigationController?.popToRootViewController(animated: true) 
        

        【讨论】:

          【解决方案10】:

          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 之一之后使用了一个视图 :)

          【讨论】:

            【解决方案11】:

            有关如何将 viewController 嵌入故事板中的 navigationController 的问题:

            1. 打开不同 viewController 所在的情节提要
            2. 点按您希望导航控制器从哪个 viewController 开始
            3. 在 Xcode 顶部,点击“编辑器”
            4. -> 点击嵌入
            5. -> 点击“导航控制器”

            【讨论】:

              【解决方案12】:

              swift 5 及以上

              案例1:使用导航控制器

              self.navigationController?.popViewController(animated: true)
              

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

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

              【讨论】:

                【解决方案13】:

                这个对我有用(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")
                        }
                      }
                    }
                }
                

                【讨论】:

                  【解决方案14】:

                  我是这样做的

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

                  【讨论】:

                    【解决方案15】:

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

                    1. 源控制器可以返回到任何其他目标控制器(不仅仅是前一个控制器),而无需了解有关目标的任何信息。
                    2. 推送和弹出转场在故事板中定义,因此您的视图控制器中没有导航代码。

                    您可以在Unwind Segues Step-by-Step 中找到更多详细信息。怎么做在前面的链接里有更好的解释,包括如何发回数据,这里我做一个简单的解释。

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

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

                    2) CTRL 从视图控制器itself 拖动到原始视图控制器中的退出图标:

                    3) 选择刚才创建的展开函数:

                    4) 选择展开转场并为其命名:

                    5) 转到原始视图控制器的任意位置并调用 unwind segue:

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

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

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

                    【讨论】:

                      猜你喜欢
                      • 2019-05-11
                      • 2015-10-23
                      • 2020-10-01
                      • 2015-08-16
                      • 1970-01-01
                      • 2019-11-14
                      • 1970-01-01
                      • 2019-05-07
                      • 1970-01-01
                      相关资源
                      最近更新 更多