如何在iOS8中使用Swift点击时隐藏/显示tabBar

我想用标签栏来模仿UINavigationController的新hidesBarsOnTap 。 我已经看到了很多的答案,要么指向设置隐藏的hidesBottomBarWhenPushed的ViewController,它只能完全隐藏它,而不是点击时隐藏。

  @IBAction func tapped(sender: AnyObject) { // what goes here to show/hide the tabBar ??? } 

提前致谢

编辑:按照下面的build议,我试过了

 self.tabBarController?.tabBar.hidden = true 

它确实隐藏了tabBar(在水龙头上切换真/假),但没有animation。 尽pipe如此,我还是会提出一个单独的问题。

经过多次狩猎和尝试各种方法优雅地隐藏/显示使用Swift的UITabBar我能够采取这个伟大的解决scheme ,并将其转换为Swift:

 func setTabBarVisible(visible:Bool, animated:Bool) { //* This cannot be called before viewDidLayoutSubviews(), because the frame is not set before this time // bail if the current state matches the desired state if (tabBarIsVisible() == visible) { return } // get a frame calculation ready let frame = self.tabBarController?.tabBar.frame let height = frame?.size.height let offsetY = (visible ? -height! : height) // zero duration means no animation let duration:NSTimeInterval = (animated ? 0.3 : 0.0) // animate the tabBar if frame != nil { UIView.animateWithDuration(duration) { self.tabBarController?.tabBar.frame = CGRectOffset(frame!, 0, offsetY!) return } } } func tabBarIsVisible() ->Bool { return self.tabBarController?.tabBar.frame.origin.y < CGRectGetMaxY(self.view.frame) } // Call the function from tap gesture recognizer added to your view (or button) @IBAction func tapped(sender: AnyObject) { setTabBarVisible(!tabBarIsVisible(), animated: true) } 

爱迈克尔Campsall的答案。 如果有人感兴趣的话,这里是和扩展名相同的代码:

Swift 2.3

 extension UITabBarController { func setTabBarVisible(visible:Bool, animated:Bool) { // bail if the current state matches the desired state if (tabBarIsVisible() == visible) { return } // get a frame calculation ready let frame = self.tabBar.frame let height = frame.size.height let offsetY = (visible ? -height : height) // animate the tabBar UIView.animateWithDuration(animated ? 0.3 : 0.0) { self.tabBar.frame = CGRectOffset(frame, 0, offsetY) self.view.frame = CGRectMake(0, 0, self.view.frame.width, self.view.frame.height + offsetY) self.view.setNeedsDisplay() self.view.layoutIfNeeded() } } func tabBarIsVisible() ->Bool { return self.tabBar.frame.origin.y < CGRectGetMaxY(self.view.frame) } } 

Swift 3

 extension UIViewController { func setTabBarVisible(visible: Bool, animated: Bool) { //* This cannot be called before viewDidLayoutSubviews(), because the frame is not set before this time // bail if the current state matches the desired state if (isTabBarVisible == visible) { return } // get a frame calculation ready let frame = self.tabBarController?.tabBar.frame let height = frame?.size.height let offsetY = (visible ? -height! : height) // zero duration means no animation let duration: TimeInterval = (animated ? 0.3 : 0.0) // animate the tabBar if frame != nil { UIView.animate(withDuration: duration) { self.tabBarController?.tabBar.frame = frame!.offsetBy(dx: 0, dy: offsetY!) return } } } var isTabBarVisible: Bool { return (self.tabBarController?.tabBar.frame.origin.y ?? 0) < self.view.frame.maxY } } 

我不得不稍微调整一下这个问题的答案。 这是隐藏酒吧,但我的看法是没有适当的大小,所以我留下了一个空间在底部。

下面的代码成功地animation化了标签栏的隐藏,同时调整了视图的大小以避免这个问题。

更新了Swift 3(现在用更less的代码)

 func setTabBarVisible(visible: Bool, animated: Bool) { guard let frame = self.tabBarController?.tabBar.frame else { return } let height = frame.size.height let offsetY = (visible ? -height : height) let duration: TimeInterval = (animated ? 0.3 : 0.0) UIView.animate(withDuration: duration, delay: 0.0, options: UIViewAnimationOptions.curveEaseIn, animations: { [weak self] () -> Void in guard let weakSelf = self else { return } weakSelf.tabBarController?.tabBar.frame = frame.offsetBy(dx: 0, dy: offsetY) weakSelf.view.frame = CGRect(x: 0, y: 0, width: weakSelf.view.frame.width, height: weakSelf.view.frame.height + offsetY) weakSelf.view.setNeedsDisplay() weakSelf.view.layoutIfNeeded() }) } func handleTap(recognizer: UITapGestureRecognizer) { setTabBarVisible(visible: !tabBarIsVisible(), animated: true) } func tabBarIsVisible() -> Bool { guard let tabBar = tabBarController?.tabBar else { return false } return tabBar.frame.origin.y < UIScreen.main.bounds.height } 

较旧的Swift 2版本

 func setTabBarVisible(visible: Bool, animated: Bool) { // hide tab bar let frame = self.tabBarController?.tabBar.frame let height = frame?.size.height var offsetY = (visible ? -height! : height) println ("offsetY = \(offsetY)") // zero duration means no animation let duration:NSTimeInterval = (animated ? 0.3 : 0.0) // animate tabBar if frame != nil { UIView.animateWithDuration(duration) { self.tabBarController?.tabBar.frame = CGRectOffset(frame!, 0, offsetY!) self.view.frame = CGRectMake(0, 0, self.view.frame.width, self.view.frame.height + offsetY!) self.view.setNeedsDisplay() self.view.layoutIfNeeded() return } } } @IBAction func handleTap(recognizer: UITapGestureRecognizer) { setTabBarVisible(!tabBarIsVisible(), animated: true) } func tabBarIsVisible() -> Bool { return self.tabBarController?.tabBar.frame.origin.y < UIScreen.mainScreen().bounds.height } 

您可以在swift中将这一行添加到ViewDidLoad()中:

 self.tabBarController?.tabBar.hidden = true 

在ObjC中我使用tabBar.hidden = YES在某些情况下隐藏标签栏。 尽pipe如此,我还没有尝试将它连接到tap事件。

代码是好的,但是当你使用presentViewControllertabBarIsVisible()不工作。 为了保持UITabBarController始终隐藏,只需使用这个部分:

 extension UITabBarController { func setTabBarVisible(visible:Bool, animated:Bool) { let frame = self.tabBar.frame let height = frame.size.height let offsetY = (visible ? -height : height) UIView.animateWithDuration(animated ? 0.3 : 0.0) { self.tabBar.frame = CGRectOffset(frame, 0, offsetY) self.view.frame = CGRectMake(0, 0, self.view.frame.width, self.view.frame.height + offsetY) self.view.setNeedsDisplay() self.view.layoutIfNeeded() } } } 

为了使animation工作与self.tabBarController?.tabBar.hidden = true只是这样做:

 UIView.animateWithDuration(0.2, animations: { self.tabBarController?.tabBar.hidden = true }) 

除了其他的解决scheme,这也将与自动布局很好地工作。