在三个视图控制器之间导航,其中三个视图控制器都在一个选项卡栏视图中

Posted

技术标签:

【中文标题】在三个视图控制器之间导航,其中三个视图控制器都在一个选项卡栏视图中【英文标题】:Navigation between three view controllers, where all three of them are in one tab bar view 【发布时间】:2019-05-15 11:11:56 【问题描述】:

我有一个标签栏视图。其中,三个选项卡之一是联系人应用程序。在那个联系人应用程序中,有三个页面,一个显示所有联系人,第二个显示在第一个 VC 中选择的一个特定联系人,第三个是添加一个新联系人。 (非常类似于内置的 ios 应用程序)如何在这三个页面之间创建流畅的流程。 (不要忘记它们应该在一个标签栏中)

我已经添加了所有必需的按钮。

首页 - 显示所有联系人 第二页 - 显示一个特定的联系人 第三页 - 添加新联系人

我已经嵌入了 3 个导航视图控制器(3 个页面各一个)

第一页有“添加”按钮,应该指向第三页。 第二页有两个按钮,一个返回第一页,另一个返回第三页。 第三个有两个按钮,每个按钮去其他两个页面。

我已经使用此功能在导航栏中以编程方式创建了这些按钮 -

    override func viewDidAppear(_ animated: Bool) 
            navigationItem.title = "Add New Contact"
            navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Done", style: UIBarButtonItem.Style.plain, target: self, action: #selector(theTransition))
       

    @objc func theTransition() 
        let second = self.storyboard?.instantiateViewController(withIdentifier: "OneNavID") as! OneNavigationViewController
        self.present(second, animated: true, completion: nil)
    

(以上代码是从第3页到第1页的示例)

这些按钮工作正常,但它们显示了一个不在标签栏控制器之外的新页面。 我希望他们留在标签视图中。请帮忙!如果您对问题有任何疑问,请询问。我已经尽力用简单而简短的语言来解释它。 我在互联网上看了很多,但我找不到任何实例,其中三个视图控制器中的每一个都有一个导航控制器(我认为这是必需的,因为它们每个都有到/从其他页面的传入和传出链接) .

第二页 -

override func viewDidAppear(_ animated: Bool) 
        navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Edit", style: UIBarButtonItem.Style.plain, target: self, action: #selector(theTransition))
    

    @objc func theTransition() 
        let second = self.storyboard?.instantiateViewController(withIdentifier: "ThreeNavID") as! ThreeNavigationViewController
        self.present(second, animated: true, completion: nil)
    

第三页 -

override func viewDidAppear(_ animated: Bool) 
        navigationItem.title = "Add New Contact"
        navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Done", style: UIBarButtonItem.Style.plain, target: self, action: #selector(theTransition))
    

    @objc func theTransition() 
        let second = self.storyboard?.instantiateViewController(withIdentifier: "NavID") as! NavigationViewController
        self.present(second, animated: true, completion: nil)
    

【问题讨论】:

外部标签栏是指视图控制器隐藏标签栏吗? 是的。我认为它创建了一个全新的 VC,因此隐藏了标签栏。等等,我会尝试分享图片。 为什么要展示VC,尝试将它们推送到navigationController 如果你在你的代码中实例化一个新的视图控制器,那么它肯定是一个新的视图控制器。同时,您正在展示该视图控制器。这也涵盖了视图。您需要为标签栏项目寻找selectItemAtIndex。使用它而不是每次都实例化视图控制器。此外,如果您正在推送视图控制器,请将视图控制器的 hidesBottomBarWhenPushed 属性设置为 false,这样它就不会隐藏您的标签栏 【参考方案1】:

不要使用 3 个导航控制器。像这样使用一个导航控制器

UITabBarController_____ Another View Controller1 
                  |  
                  |____ Another View Controller2
                  |  
                  |____ Contact - UINavigationController -- FirstPage

UINavigationController -- FirstPage --> SecondPage --> ThirdPage

在导航控制器中嵌入第一页和push 第二和第三页。不要为第一页创建新实例。使用popViewController 转到上一个视图控制器。


您可以使用 pushViewController 将数据传递给下一个视图控制器,并使用自定义委托或闭包将数据发送到前一个视图控制器。或者像这样在自定义导航控制器类中创建一个变量

class CustomNavigationController: UINavigationController 
    var name: String?

然后像这样从其他视图控制器读写数据

class FirstPage: UIViewController 
    override func viewDidLoad() 
        super.viewDidLoad()
        print((self.navigationController as? CustomNavigationController)?.name)
        (self.navigationController as? CustomNavigationController)?.name = "FirstPage"
    
    @objc func goToSecondPage() 
        if let secondPage = self.storyboard?.instantiateViewController(withIdentifier: "SecondPage") as? SecondPage 
            self.navigationController?.pushViewController(secondPage, animated: true)
        
    
    @objc func goToThirdPage() 
        if let thirdPage = self.storyboard?.instantiateViewController(withIdentifier: "ThirdPage") as? ThirdPage 
            self.navigationController?.pushViewController(thirdPage, animated: true)
        
    


class SecondPage: UIViewController 
    override func viewDidLoad() 
        super.viewDidLoad()
        print((self.navigationController as? CustomNavigationController)?.name)
        (self.navigationController as? CustomNavigationController)?.name = "SecondPage"
    
    @objc func goToThirdPage() 
        if let thirdPage = self.storyboard?.instantiateViewController(withIdentifier: "ThirdPage") as? ThirdPage 
            self.navigationController?.pushViewController(thirdPage, animated: true)
        
    
    @objc func goToFirstPage() 
        self.navigationController?.popViewController(animated: true)
    

class ThirdPage: UIViewController 
    override func viewDidLoad() 
        super.viewDidLoad()
        print((self.navigationController as? CustomNavigationController)?.name)
        (self.navigationController as? CustomNavigationController)?.name = "ThirdPage"
    
    @objc func goToFirstPage() 
        self.navigationController?.popToRootViewController(animated: true)
    
    @objc func goToSecondPage() 
        self.navigationController?.popViewController(animated: true)
    

【讨论】:

谢谢。它部分有效!但是我该怎么做才能从 2 到 3,反之亦然。实际上,我正在使用 segue 将一些数据从 2 发送到 3。它早些时候工作得很好,但自从我做了这些改变后,它就不再工作了。此外,当我从 3 回到 2 时,我希望单元格保存名称和数字等值,但它显示了一个全新的空单元格。

以上是关于在三个视图控制器之间导航,其中三个视图控制器都在一个选项卡栏视图中的主要内容,如果未能解决你的问题,请参考以下文章

使用导航控制器在视图之间导航

如何将数据从第三个视图控制器传递回第一个视图控制器?

如何在情节提要的标签栏上启动导航控制器的第三个视图控制器

将标签栏添加到导航控制器

在视图控制器之间导航的按钮

Swift - 在 UIPageViewController 中的 3 个不同视图控制器之间导航按钮