Ich versuche, die neue hidesBarsOnTap
des UINavigationControllers mit einer Tab-Leiste nachzuahmen. Ich habe viele Antworten darauf gesehen, die entweder darauf hinweisen, die hidesBottomBarWhenPushed
auf einen viewController zu setzen, der sie nur vollständig verbirgt und nicht beim Tippen.
@IBAction func tapped(sender: AnyObject) {
// what goes here to show/hide the tabBar ???
}
danke im Voraus
BEARBEITEN: gemäß dem Vorschlag unten habe ich es versucht
self.tabBarController?.tabBar.hidden = true
dadurch wird die Tab-Leiste tatsächlich ausgeblendet (wechselt zwischen wahr/falsch beim Tippen), jedoch ohne Animation. Ich werde das aber als separate Frage stellen.
Nach vielem Suchen und Ausprobieren verschiedener Methoden, um die UITabBar mit Swift elegant zu verbergen/zu zeigen, konnte ich diese großartige Lösung von danh nehmen und in Swift konvertieren:
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)
}
Liebte Michael Campsalls Antwort. Hier ist derselbe Code wie die Erweiterung, wenn jemand interessiert ist:
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
}
}
Ich musste die akzeptierte Antwort etwas an diese Frage anpassen. Es verbarg die Bar, aber mein Blick war nicht passend genug, so dass ich am Ende ein Leerzeichen hatte.
Mit dem folgenden Code wird das Ausblenden der Registerkartenleiste erfolgreich animiert, während die Größe der Ansicht geändert wird, um dieses Problem zu vermeiden.
Für Swift 3 aktualisiert (jetzt mit weniger hässlichem Code)
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
}
Ältere Swift 2 Version
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
}
Sie können diese Zeile einfach zu ViewDidLoad () in Swift hinzufügen:
self.tabBarController?.tabBar.hidden = true
Ich verwende tabBar.hidden = YES in ObjC, um die Tab-Leiste in bestimmten Fällen auszublenden. Ich habe es jedoch noch nicht versucht, es an ein Tap-Ereignis anzuschließen.
Code ist in Ordnung, aber wenn Sie presentViewController
verwenden, funktioniert tabBarIsVisible()
nicht. Um UITabBarController
immer versteckt zu halten, verwenden Sie einfach diesen Teil:
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()
}
}
}
Swift 3 Version:
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
}
Für Swift 4 und Animieren + Ausblenden durch Platzieren der TabBar außerhalb der Ansicht :
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)
}
}