简体   繁体   English

在 iOS8 中使用 Swift 轻按时如何隐藏/显示 tabBar

[英]How do I hide/show tabBar when tapped using Swift in iOS8

I am trying to mimic the UINavigationController's new hidesBarsOnTap with a tab bar.我试图用一个标签栏来模仿 UINavigationController 的新hidesBarsOnTap I have seen many answers to this that either point to setting the hidesBottomBarWhenPushed on a viewController which only hides it entirely and not when tapped.我已经看到很多对此的答案,要么指向在hidesBottomBarWhenPushed上设置hidesBottomBarWhenPushed ,它只会完全隐藏它,而不是在点击时隐藏它。

 @IBAction func tapped(sender: AnyObject) {

    // what goes here to show/hide the tabBar ???


}

thanks in advance提前致谢

EDIT: as per the suggestion below I tried编辑:根据下面的建议,我尝试过

self.tabBarController?.tabBar.hidden = true

which does indeed hide the tabBar (toggles true/false on tap), but without animation.这确实隐藏了 tabBar(点击时切换真/假),但没有动画。 I will ask that as a separate question though.不过,我会将其作为一个单独的问题提出。

After much hunting and trying out various methods to gracefully hide/show the UITabBar using Swift I was able to take this great solution by danh and convert it to Swift:在多次寻找并尝试使用 Swift 优雅地隐藏/显示 UITabBar 的各种方法之后,我能够采用 danh 提供的这个很棒的解决方案并将其转换为 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: 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
        }
    }
}

func tabBarIsVisible() -> Bool {
    return (self.tabBarController?.tabBar.frame.origin.y)! < self.view.frame.maxY
}

// Call the function from tap gesture recognizer added to your view (or button)

@IBAction func tapped(_ sender: Any?) {
    setTabBarVisible(visible: !tabBarIsVisible(), animated: true)
}

Loved Michael Campsall's answer.喜欢 Michael Campsall 的回答。 Here's the same code as extension, if somebody is interested:如果有人感兴趣,这是与扩展相同的代码:

Swift 2.3斯威夫特 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斯威夫特 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
    }
}

I had to adapt the accepted answer to this question a bit.我不得不稍微调整一下这个问题的公认答案。 It was hiding the bar but my view wasn't sizing itself appropriately so I was left with a space at the bottom.它隐藏了酒吧,但我的观点没有适当地调整自己的大小,所以我在底部留下了一个空间。

The following code successfully animates the hiding of the tab bar while resizing the view to avoid that issue.以下代码在调整视图大小以避免该问题的同时成功地为选项卡栏的隐藏设置了动画。

Updated for Swift 3 (now with less ugly code)为 Swift 3 更新(现在少了难看的代码)

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
}

Older Swift 2 Version较旧的 Swift 2 版本

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
}

您可以在 swift 中将此行添加到 ViewDidLoad() :

self.tabBarController?.tabBar.hidden = true

I use tabBar.hidden = YES in ObjC to hide the tab bar in certain cases.我在 ObjC 中使用 tabBar.hidden = YES 在某些情况下隐藏标签栏。 I have not tried wiring it up to a tap event, though.不过,我还没有尝试将其连接到点击事件。

Code is okay but when you use presentViewController , tabBarIsVisible() is not working.代码没问题,但是当您使用presentViewControllertabBarIsVisible()不起作用。 To keep UITabBarController always hidden use just this part:要保持UITabBarController始终隐藏,请仅使用以下部分:

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:斯威夫特 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
}

Swift 5斯威夫特 5

To hide隐藏

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

To show again再次显示

   override func viewDidDisappear(_ animated: Bool) {
    self.tabBarController?.tabBar.isHidden = false
  }

For Swift 4 , and animating + hiding by placing tabBar outside the view :对于Swift 4 ,通过将 tabBar 放置在视图外来设置动画+隐藏:

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

To make the animations work with self.tabBarController?.tabBar.hidden = true just do this:要使动画与self.tabBarController?.tabBar.hidden = true只需执行以下操作:

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

Other than the other solution this will also work nicely with autolayout.除了其他解决方案,这也可以很好地与自动布局配合使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM