How to hide tab bar with animation in iOS?

后端 未结 15 1937
夕颜
夕颜 2020-11-30 19:20

So I have a button that is connected to a IBAction. When I press the button I want to hide the tab bar in my iOS app with a animation. This [self setTabBarHidden:hidde

15条回答
  •  孤街浪徒
    2020-11-30 20:01

    does not longer work on iOS14, see updated 2nde answer below

    Swift 3.0 version, using an extension:

    extension UITabBarController {
        
        private struct AssociatedKeys {
            // Declare a global var to produce a unique address as the assoc object handle
            static var orgFrameView:     UInt8 = 0
            static var movedFrameView:   UInt8 = 1
        }
        
        var orgFrameView:CGRect? {
            get { return objc_getAssociatedObject(self, &AssociatedKeys.orgFrameView) as? CGRect }
            set { objc_setAssociatedObject(self, &AssociatedKeys.orgFrameView, newValue, .OBJC_ASSOCIATION_COPY) }
        }
        
        var movedFrameView:CGRect? {
            get { return objc_getAssociatedObject(self, &AssociatedKeys.movedFrameView) as? CGRect }
            set { objc_setAssociatedObject(self, &AssociatedKeys.movedFrameView, newValue, .OBJC_ASSOCIATION_COPY) }
        }
        
        override open func viewWillLayoutSubviews() {
            super.viewWillLayoutSubviews()
            if let movedFrameView = movedFrameView {
                view.frame = movedFrameView
            }
        }
        
        func setTabBarVisible(visible:Bool, animated:Bool) {
            //since iOS11 we have to set the background colour to the bar color it seams the navbar seams to get smaller during animation; this visually hides the top empty space...
            view.backgroundColor =  self.tabBar.barTintColor 
            // bail if the current state matches the desired state
            if (tabBarIsVisible() == visible) { return }
            
            //we should show it
            if visible {
                tabBar.isHidden = false
                UIView.animate(withDuration: animated ? 0.3 : 0.0) {
                    //restore form or frames
                    self.view.frame = self.orgFrameView!
                    //errase the stored locations so that...
                    self.orgFrameView = nil
                    self.movedFrameView = nil
                    //...the layoutIfNeeded() does not move them again!
                    self.view.layoutIfNeeded()
                }
            }
                //we should hide it
            else {
                //safe org positions
                orgFrameView   = view.frame
                // get a frame calculation ready
                let offsetY = self.tabBar.frame.size.height
                movedFrameView = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height + offsetY)
                //animate
                UIView.animate(withDuration: animated ? 0.3 : 0.0, animations: {
                    self.view.frame = self.movedFrameView!
                    self.view.layoutIfNeeded()
                }) {
                    (_) in
                    self.tabBar.isHidden = true
                }
            }
        }
        
        func tabBarIsVisible() ->Bool {
            return orgFrameView == nil
        }
    }
    
    • This is based on the input from Sherwin Zadeh after a few hours of playing around.
    • Instead of moving the tabbar itself it moves the frame of the view, this effectively slides the tabbar nicely out of the bottom of the screen but...
    • ... has the advantage that the content displayed inside the UITabbarcontroller is then also taking the full screen!
    • note its also using the AssociatedObject functionality to attached data to the UIView without subclassing and thus an extension is possible (extensions do not allow stored properties)

提交回复
热议问题