使用hidesBottomBarWhenPushed在推送动画期间错误地定位工具栏

时间:2015-03-29 20:13:49

标签: ios xcode storyboard

我有一个使用Tabbar进行基本导航的应用程序。从Tabbar的其中一个屏幕我想进入另一个显示工具栏而不是Tabbar和顶部的后退导航项目。

最好的方法是什么?如果我使用"在推送上隐藏底栏" (又名hidesBottomBarWhenPushed)并在屏幕上添加工具栏我可以看到在工具栏放置在屏幕底部之前删除Tabbar的动画。

6 个答案:

答案 0 :(得分:4)

问题示例

enter image description here

这是我的解决方案,

第一个视图控制器中,标签栏执行此操作

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "someSegue" {
        if let secondVC = segue.destinationViewController as? InfoTableViewController {
            secondVC.hidesBottomBarWhenPushed = true
        }
    }
}

我也需要这个,因为我的工具栏会出现在第一个VC中。

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    navigationController?.toolbarHidden = true
}

要停止工具栏的淡化动画,所以就在那里我在第二个VC

中使用了它
override func viewDidLoad() {
    super.viewDidLoad()
    navigationController?.toolbarHidden = false
}

答案 1 :(得分:3)

带工具栏的UITableViewController解决方案(需要代码)

使用this answer中的代码,我能够达到相同的效果,但工具栏位于表格视图的底部。

将此添加到您的表视图控制器:

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [self.navigationController setToolbarHidden:NO animated:YES];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    [self.navigationController setToolbarHidden:YES animated:YES];
}

重要提示:将这些来电置于viewWillAppearviewWillDisappear而不是viewDidLoad会使这更容易处理,因为即使是多次推送,它也能可靠地运行和同一个视图控制器的弹出窗口,你不必在之前的视图控制器中清理它。

在故事板中配置如下:

此外,在故事板或代码中启用隐藏底栏(时),以便推送视图控制器。

然后,您可以将工具栏按钮添加到故事板中的工具栏。

构建并运行,你会得到这种效果:

enter image description here

Here's a complete sample project demonstrating this

答案 2 :(得分:2)

纯故事板解决方案

如果您在推送过渡动画期间引用标签栏上方出现的工具栏问题,我可以通过调整故事板中工具栏上的自动布局约束来解决此问题(手动添加到您的视图控制器;如果您使用UITableViewControllerUICollectionViewController并且无法执行此操作,请参阅我的其他答案:

添加约束以将底部布局指南的距离设置为零:

双击该约束进行编辑,并将第一项设置为底部(默认情况下顶部)。

全部完成!这将产生如下效果:

Here's my sample project证明了这一点按预期工作。请注意,我没有更改任何代码,所有内容都在故事板中。

答案 3 :(得分:0)

从Xcode 7开始,纯Storyboard解决方案不再起作用,因为Xcode不允许您将Bottom属性分配给底部布局指南。

对于我的项目,我使用了以下设置:

  • 作为初始视图控制器的UITabBarController,进入
  • UINavigationController,root vc设置为...
  • UIRegularViewController,应该表现正常,但会产生......
  • UISpecialViewController,应该隐藏标签栏,而是显示工具栏。此外,它应该隐藏状态栏,导航栏和工具栏。

以下是我为实现这一目标所做的工作:

在故事板中

UITabBarController:将标签栏半透明设置为

UISpecialViewController:设置模拟指标,如此

  • 状态栏:无
  • 顶栏:Opaque Nav Bar
  • 底栏:不透明工具栏

设置扩展边,如下所示:

  • 在顶栏下:否
  • 在底栏下:是
  • 在不透明的酒吧下:是

将UIToolBar拖入UISpecialViewController

在实施中

// in UISpecialViewController.m
- (void)viewWillAppear:(BOOL)animated {
    self.navigationController.toolbarHidden = NO;
    self.navigationController.hidesBarsOnTap = YES;
}

- (void)viewWillDisappear:(BOOL)animated {

    self.navigationController.toolbarHidden = YES;
    self.navigationController.hidesBarsOnTap = NO;
}

- (BOOL)prefersStatusBarHidden {
    return self.navigationController.navigationBarHidden;
}

这是Demo Code

结果如下:

enter image description here

答案 4 :(得分:0)

实际上,UIKit已经配置了工具栏和标签栏在页面切换动画中的变化方式。

我今天也有这种情况,最终的解决方案使我感到惊讶。

例如,页面A到页面B,页面A显示Tabbar,而不是工具栏,页面B不显示Toolbar,也不显示Tabbar。

这时,B需要将hidesBottomBarWhenPushed设置为true,这是必需的。

然后,在两个ViewController的声明周期中,在A的viewWillDisappear和B的viewWillAppear中,如果设置导航控制器setToolbarHidden,则会出现此动画问题。

如果在A的viewDidDisappear和B的viewDidAppear中进行设置,则此问题已解决。尽管工具栏的动画会延迟播放,但总比错误的动画要好。

最后添加: A和B生命周期函数调用的顺序为:

  1. A-viewWillDisappear
  2. B-viewWillAppear
  3. A-viewDidDisappear
  4. B-viewDidAppear

这四种方法是交错的。

答案 5 :(得分:0)

使用 Xcode 12.4 iOS 14.4

对于那些在这个问题上挣扎并尝试上述解决方案但没有运气的人。

假设 A 仅带有 tabBar,B 仅显示工具栏

记得在 B 的 init 中设置 hidesBottomBarWhenPushed = true

override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
    super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    hidesBottomBarWhenPushed = true
}

在 B 中实现这些。(不需要在 A 中做任何事情)

override func viewDidLoad() {
    super.viewDidLoad()
    navigationController?.setToolbarHidden(true, animated: false)
}
override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()
    navigationController?.setToolbarHidden(false, animated: false)
}
override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    navigationController?.setToolbarHidden(true, animated: true)
}

就是这样!!

附言如果你想自下而上删除工具栏动画,那么添加这个

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    navigationController?.toolbar.layer.removeAnimation(forKey: "position")
}