【问题标题】:Navigate from NavigationController to another NavigationController with a back button使用后退按钮从 NavigationController 导航到另一个 NavigationController
【发布时间】:2019-12-31 08:13:30
【问题描述】:

你好, 所以我有这个storyboard 结构我在ViewController B 中有一个button 我需要button 指向底部NavigationController,其中有ViewController C 作为rootViewController 所以当我按下@ 987654330@ in ViewContoller B 带我到 C 现在我需要在 C 上的后退按钮带我回到 B

我尝试过查找,但所有参考资料都显示了如何在 ViewController 而不是 NavigationControllers 之间导航

【问题讨论】:

  • 为什么要使用第二个导航控制器?
  • @RajeshKumarR 我有一个 LocationPicker ViewController 需要从 NavigationController 的 rootViewController 打开
  • @Jhon 你可以试试我的回答,它对你的项目有用

标签: ios swift uinavigationcontroller storyboard


【解决方案1】:

我认为您不能将导航控制器推入另一个 uinavigation 控制器,但您可以提供另一个导航控制器。 希望对你有效。 我已经创建了这样的简单演示。

class ViewController: UIViewController {
    @IBOutlet weak var btnCustom: UIButton!
    override func viewDidLoad() {
        super.viewDidLoad()
    // Do any additional setup after loading the view.
    }
    @IBAction func btnForward(_ sender: Any) {
        /*Uncomment the code if you want to present programatically*/
        /*if let navi2 = self.storyboard?.instantiateViewController(withIdentifier: "nav2"){
            self.present(navi2, animated: true) {
            }
        }*/
    }

}

class ViewController2: UIViewController {
    @IBOutlet weak var btnCustom: UIButton!
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    @IBAction func btnBack(_ sender: Any) {
        if let parentNav = self.navigationController {
            parentNav.dismiss(animated: true) {

            }
        }
    }}

【讨论】:

  • 这里的“nav2”是什么,是第二个导航控制器的故事板ID吗?
  • 非常感谢。你还告诉我如何在 ViewController C 上显示默认的后退按钮
  • 你可以将 barbutton 项放在导航栏中,但你必须将 btnBack 方法与它连接
  • 你能分享一个代码sn-p吗?我对swift有点陌生
【解决方案2】:

您可以使用单个导航控制器,但覆盖后退按钮操作。

默认情况下,它将从导航堆栈中弹出当前视图控制器并转到上一个。

VC B 中的后退操作中,只需按下VC C,您可以在storyBoard 中通过从后退按钮拖放到VC C 或通过编写代码来执行此操作: p>

self.navigationControlller.push(VC C)

【讨论】:

  • 我不能使用单个 NavigationController 我有一个 LocationPicker ViewController 需要从 NavigationController 的 rootViewController 打开
【解决方案3】:

如果使用 2 navigationControllers 是无法避免的需求,可以通过以下方式解决问题陈述。

ViewControllerCUIButton's 点击事件中,在父navigationController 中获取ViewControllerB 的实例并像这样弹出它,

@objc func backAction() {
    let parentNav = self.navigationController?.navigationController
    if let vcB = parentNav?.viewControllers.first(where: { $0 is ViewControllerB }) {
        parentNav?.popToViewController(vcB, animated: true)
    }
}

backAction() 添加到backButton's 目标喜欢,

backButton.addTarget(self, action: #selector(backAction), for: .touchUpInside)

【讨论】:

  • 好的,我试过了,并使用此代码 let backButton = UIButton(type: .custom) backButton.setImage(UIImage(named: "back_icon.png"), for: .normal) backButton.setTitle("Back", for: .normal) backButton.setTitleColor(backButton.tintColor, for: .normal) backButton.addTarget(self, action: "backAction", for: .touchUpInside) self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: backButton 创建了一个后退按钮,并在点击事件中添加了您的代码,它给出了一个错误,例如“NSInvalidArgumentException”无法识别的选择器发送到实例
  • 问题是因为方法的签名和它的选择器不匹配。我已经更新了代码。
  • 我试过了,但点击后退按钮后没有任何反应
【解决方案4】:

将此代码放在 C 的 viewController 后退按钮操作方法中。此外,您必须在情节提要屏幕中为您的视图提供标识符名称。

...

//It possible to change between different storyboards, but in your case all the views share the same storyboard.

UIStoryboard* storyboardOfA_B = [UIStoryboard storyboardWithName: @"storyboardOfA_B" bundle:nil]; 
UINavigationController* navigationControllerOfA_B = [storyboardOfA_B instantiateViewControllerWithIdentifier:@"navigationControllerOfA_B"];
UIViewController* viewControllerB = [storyboardOfA_B instantiateViewControllerWithIdentifier:@"viewControllerB"];

//I'm supposing that you have the action method of the back button in the C's view controller so I use self.
UINavigationController* navigationControllerOfC = self.navigationController;

[navigationControllerOfC pushViewController: navigationControllerOfA_B animated:NO];    
[navigationControllerOfA_B pushViewController: viewControllerB animated:NO];

...

也许这不是最好的方式,但却是一种方式

【讨论】: