Подтвердить что ты не робот

Как скрыть/показать tabBar при использовании с помощью Swift в iOS8

Я пытаюсь подражать UINavigationController new hidesBarsOnTap с помощью панели вкладок. Я видел много ответов на это, которые указывают на установку hidesBottomBarWhenPushed на viewController, который только скрывает его полностью, а не при нажатии.

 @IBAction func tapped(sender: AnyObject) {

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


}

заблаговременно

ИЗМЕНИТЬ: согласно предложению ниже я пробовал

self.tabBarController?.tabBar.hidden = true

который действительно скрывает tabBar (переключает true/false при нажатии), но без анимации. Я спрошу, что в качестве отдельного вопроса.

4b9b3361

Ответ 1

После долгих поисков и опробования различных методов, чтобы изящно скрыть/показать UITabBar с помощью Swift, я смог взять это отличное решение от 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)
}

Ответ 2

Любимый Майкл Кэмпсалл ответил. Здесь тот же код, что и расширение, если кому-то интересно:

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

Ответ 3

Мне пришлось немного адаптировать принятый ответ на этот вопрос. Он скрывал планку, но мой взгляд не соответствовал должным образом, поэтому мне оставалось пространство внизу.

Следующий код успешно анимирует скрытие панели вкладок при изменении размера представления, чтобы избежать этой проблемы.

Обновлен для 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
}

Старая версия 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
}

Ответ 4

Вы можете просто добавить эту строку в ViewDidLoad() в swift:

self.tabBarController?.tabBar.hidden = true

Ответ 5

Я использую tabBar.hidden = YES в ObjC, чтобы скрыть панель вкладок в определенных случаях. Однако я не пробовал подключать его к событию с краном.

Ответ 6

Код в порядке, но когда вы используете presentViewController, tabBarIsVisible() не работает. Чтобы сохранить 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()
        }
    }
}

Ответ 7

Версия 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
}

Ответ 8

Для 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)
   }
}

Ответ 9

Чтобы анимация работала с self.tabBarController?.tabBar.hidden = true, просто выполните следующее:

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

Помимо другого решения, это также будет хорошо работать с автозапуском.