IOS / Swift - Hide / Show UITabBarController when scrolling down / up

I am very new to iOS development. Right now I am trying to hide my tab when I scroll down and when a scroll appears up the tab. I would like it to be animated just like the navigation bar. For the navigation bar, I just clicked this option in the Attributes Inspector. I saw some examples for the toolbar, but I can not accept it in the tab.

self.tabBarController?.tabBar.hidden = true just hides my tab, but not animated, like a navigation controller.

+8
ios swift uiscrollview uitabbarcontroller show-hide
source share
5 answers

This is the code that I actually use in a production application.

It is located in Swift , and also updates UITabBar.hidden var.

 func scrollViewWillBeginDragging(scrollView: UIScrollView) { if scrollView.panGestureRecognizer.translation(in: scrollView).y < 0{ changeTabBar(hidden: true, animated: true) } else{ changeTabBar(hidden: false, animated: true) } } 

You can also use another callback method:

 func scrollViewDidScroll(scrollView: UIScrollView) { ... } 

but if you choose this, then you must handle several calls to the helper method, which actually hides the tabBar.

And then you need to add this method, which animates the tabBar hiding / showing.

 func changeTabBar(hidden:Bool, animated: Bool){ var tabBar = self.tabBarController?.tabBar if tabBar!.hidden == hidden{ return } let frame = tabBar?.frame let offset = (hidden ? (frame?.size.height)! : -(frame?.size.height)!) let duration:NSTimeInterval = (animated ? 0.5 : 0.0) tabBar?.hidden = false if frame != nil { UIView.animateWithDuration(duration, animations: {tabBar!.frame = CGRectOffset(frame!, 0, offset)}, completion: { println($0) if $0 {tabBar?.hidden = hidden} }) } } 

Update Swift 4

 func changeTabBar(hidden:Bool, animated: Bool){ guard let tabBar = self.tabBarController?.tabBar else { return; } if tabBar.isHidden == hidden{ return } let frame = tabBar.frame let offset = hidden ? frame.size.height : -frame.size.height let duration:TimeInterval = (animated ? 0.5 : 0.0) tabBar.isHidden = false UIView.animate(withDuration: duration, animations: { tabBar.frame = frame.offsetBy(dx: 0, dy: offset) }, completion: { (true) in tabBar.isHidden = hidden }) } 
+33
source share

Based on Ariel's answer, I updated the code for Swift3 . This is reflected in my presentation of the collection.

 override func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) { if scrollView.panGestureRecognizer.translation(in: scrollView).y < 0 { changeTabBar(hidden: true, animated: true) }else{ changeTabBar(hidden: false, animated: true) } } func changeTabBar(hidden:Bool, animated: Bool){ let tabBar = self.tabBarController?.tabBar if tabBar!.isHidden == hidden{ return } let frame = tabBar?.frame let offset = (hidden ? (frame?.size.height)! : -(frame?.size.height)!) let duration:TimeInterval = (animated ? 0.5 : 0.0) tabBar?.isHidden = false if frame != nil { UIView.animate(withDuration: duration, animations: {tabBar!.frame = frame!.offsetBy(dx: 0, dy: offset)}, completion: { print($0) if $0 {tabBar?.isHidden = hidden} }) } } 
+5
source share

This answer is a small modification of Ariel's answer, which adds animation as the user scrolls.

 extension ViewController:UIScrollViewDelegate{ func scrollViewDidScroll(_ scrollView: UIScrollView) { if scrollView.panGestureRecognizer.translation(in: scrollView).y < 0{ //scrolling down changeTabBar(hidden: true, animated: true) } else{ //scrolling up changeTabBar(hidden: false, animated: true) } } func changeTabBar(hidden:Bool, animated: Bool){ let tabBar = self.tabBarController?.tabBar let offset = (hidden ? UIScreen.main.bounds.size.height : UIScreen.main.bounds.size.height - (tabBar?.frame.size.height)! ) if offset == tabBar?.frame.origin.y {return} print("changing origin y position") let duration:TimeInterval = (animated ? 0.5 : 0.0) UIView.animate(withDuration: duration, animations: {tabBar!.frame.origin.y = offset}, completion:nil) } } 
+4
source share

You can precisely control the UITabBar by setting your class as a delegate for scrollView and implementing scroll in the scrollViewDidScroll: method.

Here is an example of how I am making this my application. You can probably easily change this for your needs. Some helper function to enable UITabBar.

 #define LIMIT(__VALUE__, __MIN__, __MAX__) MAX(__MIN__, MIN(__MAX__, __VALUE__)) - (void)scrollViewDidScroll:(UIScrollView *)scrollView { CGFloat scrollOffset = scrollView.contentOffset.y; CGFloat scrollDiff = scrollOffset - self.previousScrollViewYOffset; CGFloat scrollHeight = scrollView.frame.size.height; CGFloat scrollContentSizeHeight = scrollView.contentSize.height + scrollView.contentInset.bottom; CGFloat scrollOffsetGlobal = scrollOffset + scrollView.contentInset.top; [self updateUITabBarY:[self UITabBarView].frame.origin.y + scrollDiff]; self.previousScrollViewYOffset = scrollOffset; } - (UITabBar*) UITabBarView { for(UIView *view in self.tabBarController.view.subviews) { if([view isKindOfClass:[UITabBar class]]) { return (UITabBar*) view; } } return nil; } - (void) updateUITabBarY:(CGFloat) y { UITabBar* tabBar = [self UITabBarView]; if(tabBar) { CGRect frame = tabBar.frame; frame.origin.y = LIMIT(y, [self UITabBarMiny], [self UITabBarMaxY]); tabBar.frame = frame; } } - (CGFloat) UITabBarMiny { return [UIScreen mainScreen].bounds.size.height - [self UITabBarView].frame.size.height - [[UIApplication sharedApplication] statusBarFrame].size.height + 20.0f; } - (CGFloat) UITabBarMaxY { return [UIScreen mainScreen].bounds.size.height; } 
0
source share

According to @Ariel Hernández Amador, the answer for the black screen after hiding the Tabbar is to simply use this line of code. Works great ... I posted it here, as I cannot comment there.

if #available(iOS 11.0, *) { self.myScroll.contentInsetAdjustmentBehavior =.never }

Here myScroll is the Scrollview that I use in my VC. Just replace it with your VK.

0
source share

All Articles