How to hide tab bar with animation in iOS?

So, I have a button connected to IBAction. When I click the button, I want to hide the tab bar in my iOS application using animation. This [self setTabBarHidden:hidden animated:NO]; or this [self.tabBarController setTabBarHidden:hidden animated:YES]; does not work. This is my code without animation:

 - (IBAction)picture1:(id)sender { [self.tabBarController.tabBar setHidden:YES]; } 

Any help would be greatly appreciated: D

+44
ios uitabbarcontroller ibaction uitabbar
Jan 05 '14 at 15:15
source share
10 answers

I am trying to keep the viewing animation available to me using the following formula:

 // pass a param to describe the state change, an animated flag and a completion block matching UIView animations completion - (void)setTabBarVisible:(BOOL)visible animated:(BOOL)animated completion:(void (^)(BOOL))completion { // bail if the current state matches the desired state if ([self tabBarIsVisible] == visible) return (completion)? completion(YES) : nil; // get a frame calculation ready CGRect frame = self.tabBarController.tabBar.frame; CGFloat height = frame.size.height; CGFloat offsetY = (visible)? -height : height; // zero duration means no animation CGFloat duration = (animated)? 0.3 : 0.0; [UIView animateWithDuration:duration animations:^{ self.tabBarController.tabBar.frame = CGRectOffset(frame, 0, offsetY); } completion:completion]; } //Getter to know the current state - (BOOL)tabBarIsVisible { return self.tabBarController.tabBar.frame.origin.y < CGRectGetMaxY(self.view.frame); } //An illustration of a call to toggle current state - (IBAction)pressedButton:(id)sender { [self setTabBarVisible:![self tabBarIsVisible] animated:YES completion:^(BOOL finished) { NSLog(@"finished"); }]; } 
+62
Jan 05 '14 at 16:05
source share

When working with the storyboard, it’s easy to configure the view controller to hide the tab when clicked, on the target view controller, just select this check box:
enter image description here

+76
Feb 28 '15 at 21:52
source share

According to Apple's docs, hidesBottomBarWhenPushed, the UIViewController property is a Boolean value that indicates whether the toolbar is hidden at the bottom of the screen when the view controller is pressed on the navigation controller.

The value of this property on the top view controller determines whether the toolbar is visible.

The recommended approach to hiding the tab bar is as follows

  ViewController *viewController = [[ViewController alloc] init]; viewController.hidesBottomBarWhenPushed = YES; // This property needs to be set before pushing viewController to the navigationController stack. [self.navigationController pushViewController:viewController animated:YES]; 

However, note that this approach will only apply to the corresponding viewController and will not apply to other view controllers unless you start setting the same hidesBottomBarWhenPushed property in other viewControllers before pushing it onto the navigation controller stack.

+25
Jan 05 '14 at 16:18
source share

Quick version:

 @IBAction func tap(sender: AnyObject) { setTabBarVisible(!tabBarIsVisible(), animated: true, completion: {_ in }) } // pass a param to describe the state change, an animated flag and a completion block matching UIView animations completion func setTabBarVisible(visible: Bool, animated: Bool, completion:(Bool)->Void) { // bail if the current state matches the desired state if (tabBarIsVisible() == visible) { return completion(true) } // get a frame calculation ready let height = tabBarController!.tabBar.frame.size.height let offsetY = (visible ? -height : height) // zero duration means no animation let duration = (animated ? 0.3 : 0.0) UIView.animateWithDuration(duration, animations: { let frame = self.tabBarController!.tabBar.frame self.tabBarController!.tabBar.frame = CGRectOffset(frame, 0, offsetY); }, completion:completion) } func tabBarIsVisible() -> Bool { return tabBarController!.tabBar.frame.origin.y < CGRectGetMaxY(view.frame) } 
+9
Mar 16 '16 at 1:35
source share

version of Swift 3.0 using the extension:

 extension UITabBarController { private struct AssociatedKeys { // Declare a global var to produce a unique address as the assoc object handle static var orgFrameView: UInt8 = 0 static var movedFrameView: UInt8 = 1 } var orgFrameView:CGRect? { get { return objc_getAssociatedObject(self, &AssociatedKeys.orgFrameView) as? CGRect } set { objc_setAssociatedObject(self, &AssociatedKeys.orgFrameView, newValue, .OBJC_ASSOCIATION_COPY) } } var movedFrameView:CGRect? { get { return objc_getAssociatedObject(self, &AssociatedKeys.movedFrameView) as? CGRect } set { objc_setAssociatedObject(self, &AssociatedKeys.movedFrameView, newValue, .OBJC_ASSOCIATION_COPY) } } override open func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() if let movedFrameView = movedFrameView { view.frame = movedFrameView } } func setTabBarVisible(visible:Bool, animated:Bool) { //since iOS11 we have to set the background colour to the bar color it seams the navbar seams to get smaller during animation; this visually hides the top empty space... view.backgroundColor = self.tabBar.barTintColor // bail if the current state matches the desired state if (tabBarIsVisible() == visible) { return } //we should show it if visible { tabBar.isHidden = false UIView.animate(withDuration: animated ? 0.3 : 0.0) { //restore form or frames self.view.frame = self.orgFrameView! //errase the stored locations so that... self.orgFrameView = nil self.movedFrameView = nil //...the layoutIfNeeded() does not move them again! self.view.layoutIfNeeded() } } //we should hide it else { //safe org positions orgFrameView = view.frame // get a frame calculation ready let offsetY = self.tabBar.frame.size.height movedFrameView = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height + offsetY) //animate UIView.animate(withDuration: animated ? 0.3 : 0.0, animations: { self.view.frame = self.movedFrameView! self.view.layoutIfNeeded() }) { (_) in self.tabBar.isHidden = true } } } func tabBarIsVisible() ->Bool { return orgFrameView == nil } } 
  • This is based on the contribution of Sherwin Zadeh after several hours of play.
  • Instead of moving the tab itself, it moves the view frame, it effectively slides the tab well from the bottom of the screen, but ...
  • ... has the advantage that the content displayed inside the UITabbarcontroller also accepts the entire screen!
  • note that it also uses the AssociatedObject functionality for attached data to a UIView without a subclass and, therefore, an extension is possible (extensions do not allow saving saved properties).

enter image description here

+9
Jun 22 '17 at 18:46
source share

Try setting the tabBar frame in the animation. See this tutorial.

Just keep in mind that this is bad practice, you should set the show / hide tabBar when the UIViewController setting the hidesBottomBarWhenPushed property to YES .

+3
Jan 05 '14 at 15:38
source share

tried in swift 3.0 / iOS10 / Xcode 8:

  self.tabBarController?.tabBar.isHidden = true 

I install it when my controller is displayed: (and Hide when it returned, after navigation)

 override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) self.tabBarController?.tabBar.isHidden = false } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) self.tabBarController?.tabBar.isHidden = true } 

BTW: it is better to have a flag to save if it is shown or not, as other ventilation openings may eventually cause hide / show

+1
Dec 11 '16 at 7:42
source share

Unfortunately, I cannot comment on the HixField answer because I do not have enough reputation, so I have to leave this as a separate answer.

His answer lacks a computed property for movedFrameView , which:

 var movedFrameView:CGRect? { get { return objc_getAssociatedObject(self, &AssociatedKeys.movedFrameView) as? CGRect } set { objc_setAssociatedObject(self, &AssociatedKeys.movedFrameView, newValue, .OBJC_ASSOCIATION_COPY) } } 
+1
Aug 04 '17 at 21:05
source share

Rewrite Sherwin Zadeh's answer in Swift 4:

 /* tab bar hide/show animation */ extension AlbumViewController { // pass a param to describe the state change, an animated flag and a completion block matching UIView animations completion func setTabBarVisible(visible: Bool, animated: Bool, completion: ((Bool)->Void)? = nil ) { // bail if the current state matches the desired state if (tabBarIsVisible() == visible) { if let completion = completion { return completion(true) } else { return } } // get a frame calculation ready let height = tabBarController!.tabBar.frame.size.height let offsetY = (visible ? -height : height) // zero duration means no animation let duration = (animated ? kFullScreenAnimationTime : 0.0) UIView.animate(withDuration: duration, animations: { let frame = self.tabBarController!.tabBar.frame self.tabBarController!.tabBar.frame = frame.offsetBy(dx: 0, dy: offsetY) }, completion:completion) } func tabBarIsVisible() -> Bool { return tabBarController!.tabBar.frame.origin.y < view.frame.maxY } } 
0
Sep 20 '17 at 10:41
source share

This is for me: [self.tabBar setHidden:YES];
where self is the view controller, tabBar is the identifier for tabBar.

-5
Sep 18 '14 at 6:07
source share



All Articles