web-dev-qa-db-ja.com

iOS8でSwiftを使用してタップしたときにtabBarを非表示/表示するにはどうすればよいですか

UINavigationControllerの新しいhidesBarsOnTapをタブバーで模倣しようとしています。これに対する多くの回答を見てきましたが、いずれもタップしたときではなく、完全に非表示にするviewControllerでhidesBottomBarWhenPushedを設定することを指します。

 @IBAction func tapped(sender: AnyObject) {

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


}

前もって感謝します

編集:以下の提案に従って私が試した

self.tabBarController?.tabBar.hidden = true

実際にはtabBarは非表示になります(タップするとtrue/falseが切り替わります)が、アニメーションは表示されません。ただし、それは別の質問としてお願いします。

26

Swift私は danhによるこの素晴らしい解決策 を使用してUITabBarを優雅に非表示/表示するさまざまな方法を試し、それを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)
}
52

マイケルキャンプソールの答えが大好き。誰かが興味を持っているなら、これは拡張と同じコードです:

Swift 2.

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

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

この質問に対する受け入れられた答えを少し適応させなければなりませんでした。それはバーを隠していましたが、私のビューは適切にサイジングされていなかったので、下部にスペースが残っていました。

次のコードは、この問題を回避するためにビューのサイズを変更しながら、タブバーの非表示を正常にアニメーション化します。

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

この行をViewDidLoad()にSwiftで追加するだけです:

self.tabBarController?.tabBar.hidden = true
6
MichelRobico

特定の場合にタブバーを非表示にするには、ObjCでtabBar.hidden = YESを使用します。ただし、タップイベントへの接続は試みていません。

2
Mike Taverne

コードは問題ありませんが、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()
        }
    }
}
2
fatihyildizhan

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

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