以编程方式返回到Swift中以前的ViewController


211

我将用户带到单击按钮的页面上。此页面是UITableViewController

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

我想到了类似的东西,self.performSegue("back")....但这似乎是个坏主意。

正确的方法是什么?


13
self.navigationController?.popViewControllerAnimated(true)
Kalpesh

Answers:


526

斯威夫特3:

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

_ = navigationController?.popViewController(animated: true)

如果要返回到根视图控制器

_ = navigationController?.popToRootViewController(animated: true)

1
轻按单元格后如何将数据发送回previousController?如果我们使用的是navigationController?.popViewControllerAnimated(true)
JDDelgado 2015年


36
对于Swift 3,它是.popViewController(animated: true)
Sasho

9
发出任何警告:_ = self.navigationController?.popToRootViewController(animated: true)
Andrew K

1
我们忽略了返回值;_ = 迅速做到这一点的惯例。
安德鲁K

53

迅捷3迅捷4

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

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


@Vyacheslva我收到一个错误“在封闭中隐式使用'seft',使用'self'使捕获语义显式”
Sandip Subedi 17-4-20

@SandipSubedi使用[weak self]self?.navigationController?.
Vyacheslav

这是有用的,但我想送导航一些变量,但现在我不能-我用 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if let vc = segue.destination as? ,但用这个当我我不能使用
赛义德Rahmatolahi

怎么添加navigationController呢?
user25

@ user25添加?你什么意思?
Vyacheslav '18

37

迅捷3

我的答案可能太迟了,但是对于敏捷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)
}

3
这不是“完全”正确的。如果呈现的视图控制器包含其自己的导航,则在按下视图控制器后使用该方法,dismiss:它不仅会关闭当前的视图控制器,还会关闭根视图控制器,这不是这里要问的。
埃内斯托·费尔南德斯

2
该问题并未询问用户是否具有导航控制器。对于没有导航控制器的用户来说,这是最简单,最好的答案。这确实应该是公认的答案。
Droid Chris

谢谢Droid-嗨ernestofndz,您可能会说对,也将关闭rootVC,但这对我而言不会发生,它只会关闭currentVC,我是通过编程方式添加和删除项,并且可能不是相同的方法与情节提要上的正常添加元素..更正我的理解,如果我错了...对于tableView,如果用户需要将详细信息传递给另一个View,则这是另一种情况,与我发布的内容没有任何联系,并会100%同意与您一起..据我所知,在这种情况下需要后退按钮:)
Fullpower

也许你可以添加一些介绍..因为存在dismiss&navigationController?.popViewController
marlonpya

dismiss(animated: true, completion: nil)旋转后不起作用!
user924

31

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


19

如果您UIViewControllerUIViewControllerie。中提出一个。

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

只需调用该dismiss函数:

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

self.dismiss(animated: true)-旋转后无法使用
user924

17

迅速5以上

情况1:与导航控制器一起使用

self.navigationController?.popViewController(animated: true)

情况2:与当前视图控制器一起使用

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

11

如果Segue是'Show'或'Push'的种类,则可以在UINavigationController的实例上调用“ popViewController(animated:Bool)”。或者,如果segue有点“存在”,则使用UIViewController实例调用“ dismiss(动画:Bool,完成:(()-> Void)?)”


7

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

_ = navigationController?.popViewController(animated: true)

2

尝试以下操作:对于以前的视图,请使用以下命令:

navigationController?.popViewController(animated: true)  

弹出到根使用此代码:

navigationController?.popToRootViewController(animated: true) 

2

使用TabViewController作为最后一个视图的Swift 4.0 Xcode 10.0

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

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

但是,如果您确实想返回到最后一个视图(可以是Tab1,Tab2或Tab3视图。),则必须编写以下代码:

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

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


1

有关如何将您的viewController嵌入情节提要中的navigationController的问题:

  1. 打开您的其他viewController所在的情节提要
  2. 点击您要导航控制器开始的viewController
  3. 在Xcode的顶部,点击“编辑器”
  4. ->点击嵌入
  5. ->点击“导航控制器

1

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

0

我是这样做的

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

0

我想提出另一种解决这个问题的方法。不要使用导航控制器来弹出视图控制器,而要使用展开控件。该解决方案具有一些但非常重要的优点:

  1. 原始控制器可以返回到任何其他目标控制器(而不仅仅是前一个),而无需了解任何有关目标的信息。
  2. 推送和弹出序列是在情节提要中定义的,因此视图控制器中没有导航代码。

您可以在“ 逐步解开谜题”中找到更多详细信息。在前面的链接中,如何更好地解释了方法,包括如何将数据发送回去,但是在这里,我将做一个简短的解释。

1)转到目标(而不是原点)视图控制器,并添加展开顺序:

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

2)CTRL从视图控制器本身拖动到原点视图控制器中的退出图标:

从视图控制器展开

3)选择您刚才创建的展开功能:

选择展开功能

4)选择放宽序列并为其命名:

命名放松的segue

5)转到原点视图控制器的任何位置,然后调用展开命令:

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

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

我希望这可以帮助别人。


-3

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

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


即使您要在层次结构中向前移动,这也会导致导航控制器弹出到根目录。
bkSwifty
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.