所以我有一个连接到IBAction的按钮.当我按下按钮时,我想用动画隐藏iOS应用程序中的标签栏.这个[self setTabBarHidden:hidden animated:NO];
或这个[self.tabBarController setTabBarHidden:hidden animated:YES];
不起作用.这是没有动画的代码:
- (IBAction)picture1:(id)sender { [self.tabBarController.tabBar setHidden:YES]; }
任何帮助将不胜感激:D
根据Apple文档,hidesBottomBarWhenPushed属性UIViewController,一个布尔值,指示当视图控制器被推送到导航控制器时是否隐藏屏幕底部的工具栏.
最顶层视图控制器上此属性的值确定工具栏是否可见.
隐藏标签栏的推荐方法如下
ViewController *viewController = [[ViewController alloc] init]; viewController.hidesBottomBarWhenPushed = YES; // This property needs to be set before pushing viewController to the navigationController's stack. [self.navigationController pushViewController:viewController animated:YES];
但是,请注意,此方法仅应用于相应的viewController,并且不会传播到其他视图控制器,除非您在将其推送到导航控制器的堆栈之前开始在其他viewControllers中设置相同的hidesBottomBarWhenPushed属性.
Swift 3.0版,使用扩展名:
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 } }
这是基于Sherwin Zadeh在几个小时的游戏后的输入.
而不是移动tabbar本身它移动视图的框架,这有效地滑动tabbar很好地从屏幕的底部,但......
...的优势在于UITabbarcontroller内显示的内容也可以全屏显示!
请注意它也使用AssociatedObject功能将数据附加到UIView而不进行子类化,因此可以进行扩展(扩展不允许存储属性)
我尝试使用以下公式保持查看动画:
// 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"); }]; }
Swift版本:
@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) }
在Swift 4中重写Sherwin Zadeh的答案:
/* 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 } }
使用故事板时,可以轻松设置View Controller以在推送时隐藏标签栏,在目标View Controller上选择此复选框: