在不显示标签栏的情况下执行对另一个导航控制器的 segue

Posted

技术标签:

【中文标题】在不显示标签栏的情况下执行对另一个导航控制器的 segue【英文标题】:Perform segue to another Navigation Controller without showing Tab Bar 【发布时间】:2016-01-27 22:11:39 【问题描述】:

我有一个根 Tab Host Controller 和两个 Navigation Controller 选项卡兄弟姐妹:(1) 附近站点和 (2) 已保存站点。其中每一个都有一个View Controller

我想执行从其中一个兄弟 View Controllers 到另一个 Navigation Controller 的转场,其中嵌入了 Stop Schedule View Controller,并满足以下要求:

    Tab Bar 不应显示在此View Controller 的底部 在执行 segue 之前,我需要将 Stop 对象传递给此视图控制器

故事板:

目前,我正在以这种方式执行 segue,尽管 Tab Bar 不应该保留在 Stop Schedule View Controller 上。

func showStopSchedule(stop: Stop) 
    let stopScheduleController = self.storyboard?.instantiateViewControllerWithIdentifier("StopScheduleViewController") as! StopScheduleViewController

    stopScheduleController.stop = stop    // pass data object

    self.navigationController?.pushViewController(stopScheduleController, animated: true)

【问题讨论】:

为什么在停止计划控制器前面有额外的导航控制器? 我包含它是为了使标签栏不会包含在视图控制器中。 好的,所以删除它,然后在需要时使用我的答案中的代码隐藏标签栏。这也将使用户导航更简单,因为他们可以简单地回到他们开始的地方。 SwiftArchitect 也是正确的;您没有在情节提要中使用segue。可以使用performSegueWithIdentifierprepareForSegue通过站台 【参考方案1】:

您可以在显示停止计划视图控制器时简单地设置标签栏的hidden 属性,并在该视图控制器消失之前取消隐藏标签栏

override func viewWillAppear(animated: Bool) 
    super.viewWillAppear(animated)
    self.tabBarController?.tabBar.hidden=true


override func viewWillDisappear(animated: Bool) 
    super.viewWillDisappear(animated)
    self.tabBarController?.tabBar.hidden=false

更新:要为过渡设置动画,您可以使用:

class StopViewController: UIViewController 

    var barFrame:CGRect?

    override func viewDidLoad() 
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    

    override func viewWillAppear(animated: Bool) 

        super.viewWillAppear(animated)
        // self.tabBarController?.tabBar.hidden=true
        if  let tabBar=self.tabBarController?.tabBar 
           self.barFrame=tabBar.frame

           UIView.animateWithDuration(0.3, animations:  () -> Void in
               let newBarFrame=CGRectMake(self.barFrame!.origin.x, self.view.frame.size.height, self.barFrame!.size.width, self.barFrame!.size.height)
               tabBar.frame=newBarFrame
            , completion:  (Bool) -> Void in
                tabBar.hidden=true
            )

        
    

    override func viewWillDisappear(animated: Bool) 
        super.viewWillDisappear(animated)
        self.tabBarController?.tabBar.hidden=false;
        if self.barFrame != nil 
            UIView.animateWithDuration(0.3, animations:  () -> Void in
                let newBarFrame=CGRectMake(self.barFrame!.origin.x, self.view.frame.size.height-self.barFrame!.size.height, self.view.frame.size.width, self.barFrame!.size.height)
                self.tabBarController?.tabBar.frame=newBarFrame
            )

        
    

【讨论】:

这确实隐藏了标签栏,尽管当视图控制器出现时标签栏上有一个明显的淡入淡出动画。 这是一个权衡。就我个人而言,我更喜欢它而不是使用第二个导航控制器获得的模态转换,并且不会丢失导航堆栈。请参阅我的更新答案以获取动画替代方案 感谢 Paulw11,我会尝试您的解决方案和 SwiftArchitect,看看哪个效果最好。 @Paulw11:漂亮! 我更新了我的代码,以防止标签栏在设备旋转时短暂出现,并在设备在返回第一个视图之前旋转时正常运行【参考方案2】:

您没有使用刚刚在 Storyboard 中定义的 segue。相反,您当前正在手动重新加载您的StopScheduleViewController,而您应该只执行您已经定义的segue

向您要以编程方式调用的每个Storyboard Segue添加一个标识符

然后以这种方式加载它们:

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) 
    performSegueWithIdentifier("showStopSchedule", sender: self)

【讨论】:

虽然这是正确的,但它并没有回答关于如何隐藏标签栏的问题。这应该是一条评论。 确实如此。加载 segue 会隐藏标签栏。 嗯,是的。我没有注意到他们在最终视图控制器前面插入的附加导航控制器。这可能是不必要的 使用这种方法,我怎样才能将Stop 对象也传递给视图控制器? 使用- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender,见***.com/questions/20017026/…【参考方案3】:

如果你只想隐藏 navigationController,下面的代码可以工作。

  self.navigationController?.navigationBar.hidden = true

【讨论】:

以上是关于在不显示标签栏的情况下执行对另一个导航控制器的 segue的主要内容,如果未能解决你的问题,请参考以下文章

如何在不使用导航栏的情况下从导航堆栈中弹出控制器

如何在不点击导航栏的情况下使用 BottomNavigation 进行导航

在不影响导航栏的情况下更改 NavigationController 的内容视图宽度

在不改变顶栏的情况下切换 UIView

在不使用导航控制器的情况下转到第二个视图时如何显示动画?

如何在不使用导航控制器的情况下推送 UIViewController?