tab bar ios swift ios8 uitabbarcontroller

¿Cómo oculto/muestro tabBar cuando se pulsa con Swift en iOS8?



uitabbarcontroller programmatically swift (9)

Después de mucho cazar y probar varios métodos para ocultar / mostrar graciosamente la barra de la UITabBar usando Swift, pude tomar esta gran solución de danh y convertirla en 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) }

Estoy tratando de imitar el nuevo hidesBarsOnTap del hidesBarsOnTap con una barra de pestañas. He visto muchas respuestas a esto que apuntan a configurar el hidesBottomBarWhenPushed en un viewController que solo lo oculta por completo y no cuando se toca.

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

gracias por adelantado

EDITAR: según la sugerencia a continuación he intentado

self.tabBarController?.tabBar.hidden = true

que de hecho oculta el tabBar (alterna verdadero / falso al tocar), pero sin animación. Sin embargo, lo preguntaré como una pregunta aparte.


El código está bien, pero cuando usa presentViewController , tabBarIsVisible() no funciona. Para mantener el UITabBarController siempre oculto, use esta parte:

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() } } }


Me encantó la respuesta de Michael Campsall. Aquí está el mismo código que la extensión, si alguien está interesado:

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 } }


Para Swift 4 , y animación + ocultación colocando tabBar fuera de la vista :

if let tabBar = tabBarController?.tabBar, let y = tabBar.frame.origin.y + tabBar.frame.height { UIView.animate(withDuration: 0.2) { tabBar.frame = CGRect(origin: CGPoint(x: tabBar.frame.origin.x, y: y), size: tabBar.frame.size) } }


Para hacer que las animaciones funcionen con self.tabBarController?.tabBar.hidden = true solo haz esto:

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

Aparte de la otra solución, esto también funcionará bien con el autolayout.


Solo puede agregar esta línea a ViewDidLoad () en swift:

self.tabBarController?.tabBar.hidden = true


Tuve que adaptar un poco la respuesta aceptada a esta pregunta. Estaba escondiendo la barra, pero mi vista no se estaba dimensionando adecuadamente, así que me quedé con un espacio en la parte inferior.

El siguiente código anima con éxito la ocultación de la barra de pestañas mientras cambia el tamaño de la vista para evitar ese problema.

Actualizado para Swift 3 (ahora con un código menos feo)

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 }

Versión Swift 2 más antigua

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 }


Uso tabBar.hidden = YES en ObjC para ocultar la barra de pestañas en ciertos casos. Sin embargo, no he intentado conectarlo a un evento de tap.


Versión Swift 3:

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:TimeInterval = (animated ? 0.3 : 0.0) // animate the tabBar if frame != nil { UIView.animate(withDuration: duration) { self.tabBarController?.tabBar.frame = (self.tabBarController?.tabBar.frame.offsetBy(dx: 0, dy: offsetY!))! return } } } func tabBarIsVisible() ->Bool { return (self.tabBarController?.tabBar.frame.origin.y)! < self.view.frame.midY }