Search code examples
iosswiftswift3uitabbarcontrolleruitabbar

Tab Bar controller on iphone x


I now this is duplicated question but not any solution solve my problem. I'm new in IOS and i'm using TabBar Controller in my project using swift 4. TabBar is working perfect but design issues on Iphone X. Storyboard preview is ok on IphonX but Simulator and devices showing design issue.. view my storyboard enter image description here

i'm not using any custom view for TabBar. I have also checked used safe area layouts guides in my project. enter image description here

and my TabBar controller code is

import UIKit

class TabBarSingleton: NSObject {

   static let sharedInstance = TabBarSingleton()
   var tabBarObject : UITabBar?

   override  init(){}
    }

   class TabBarViewController: 
   UITabBarController,UITabBarControllerDelegate {
   let userID =   PSStateManager.sharedManager.userId
   override func viewDidLoad() {
    super.viewDidLoad()
   TabBarSingleton.sharedInstance.tabBarObject = self.tabBar
    for vc in viewControllers!{
        vc.tabBarItem.imageInsets=UIEdgeInsetsMake(-2, 0, +2, 0)
    }
    self.tabBar.unselectedItemTintColor = UIColor.init(hexString: "#5E5E5E")
    self.tabBar.tintColor=UIColor.init(hexString: "#36C4E5")
    self.delegate = self
    self.tabBar.barTintColor = themeColor
    self.tabBar.isTranslucent = false

    self.changeSelectionColor()
    // Do any additional setup after loading the view.
}

override func viewWillAppear(_ animated: Bool) {
   super.viewWillAppear(true)


    patientStatisticCallerFunc(userID: userID!) { (model) in
    return
    }
}


override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
    let navVC = selectedViewController as! PSNavigationViewController
    navVC.popToRootViewController(animated: false)
    navVC.updateNavBar()
}

func changeSelectionColor() {
    let numberOfItems = CGFloat(tabBar.items!.count)
    let tabBarItemSize = CGSize(width: tabBar.frame.width / numberOfItems, height: tabBar.frame.height)
    tabBar.selectionIndicatorImage = UIImage.imageWithColor(color: UIColor.white, size: tabBarItemSize).resizableImage(withCapInsets: .zero)
    // remove default border
    tabBar.frame.size.width = self.view.frame.width + 4
    tabBar.frame.origin.x = -2
    // tab bar item tint color for selected and unselected and font size
    let colorNormal : UIColor = UIColor.init(hexString: "#5E5E5E")
    let selectedColor : UIColor = UIColor.init(hexString: "#36C4E5")

        let titleFontAll : UIFont = UIFont(name: "segoeui", size: 9.0)!

        let attributesNormal = [
            NSAttributedStringKey.foregroundColor : colorNormal,
            NSAttributedStringKey.font : titleFontAll
        ]

        let attributesSelected = [
            NSAttributedStringKey.foregroundColor : selectedColor,
            NSAttributedStringKey.font : titleFontAll
        ]
        UITabBarItem.appearance().setTitleTextAttributes(attributesNormal, for: .normal)
        UITabBarItem.appearance().setTitleTextAttributes(attributesSelected, for: .selected)
        UITabBarItem.appearance().titlePositionAdjustment = UIOffset(horizontal: 0, vertical: -3)

}

func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
    self.changeSelectionColor()

}

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    if #available(iOS 11.0, *) {
        self.tabBar.insetsLayoutMarginsFromSafeArea = true
    }
    self.tabBar.invalidateIntrinsicContentSize()
}
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
    let tabViewControllers = tabBarController.viewControllers!
    guard let toIndex = tabViewControllers.index(of: viewController) else {
        return false
    }

    animateToTab(toIndex: toIndex)

    return true
}

func animateToTab(toIndex: Int) {
    let tabViewControllers = viewControllers!
    let fromView = selectedViewController!.view
    let toView = tabViewControllers[toIndex].view
    let fromIndex = tabViewControllers.index(of: selectedViewController!)

    guard fromIndex != toIndex else {return}

    // Add the toView to the tab bar view
    fromView?.superview!.addSubview(toView!)

    // Position toView off screen (to the left/right of fromView)
    let screenWidth = UIScreen.main.bounds.size.width;
    let scrollRight = toIndex > fromIndex!;
    let offset = (scrollRight ? screenWidth : -screenWidth)
    toView?.center = CGPoint(x: (fromView?.center.x)! + offset, y: (toView?.center.y)!)

    // Disable interaction during animation
    view.isUserInteractionEnabled = false

    UIView.animate(withDuration: mediumTranstionDuration, delay: 0.0, usingSpringWithDamping: 1, initialSpringVelocity: 0, options: UIViewAnimationOptions.curveEaseOut, animations: {

        // Slide the views by -offset
        fromView?.center = CGPoint(x: (fromView?.center.x)! - offset, y: (fromView?.center.y)!);
        toView?.center   = CGPoint(x: (toView?.center.x)! - offset, y: (toView?.center.y)!);

    }, completion: { finished in

        // Remove the old view from the tabbar view.
        fromView?.removeFromSuperview()
        self.selectedIndex = toIndex
        self.view.isUserInteractionEnabled = true
    })
}
func changeLabelColors(inView: UIView) {

}
/*
// MARK: - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    // Get the new view controller using segue.destinationViewController.
    // Pass the selected object to the new view controller.
}
*/

}

and i'm facing this issue enter image description here


Solution

  • I was having the same issue and was solved using this class for my UITabBar,

    @IBDesignable class CustomTabBar: UITabBar {
    
    @IBInspectable var height: CGFloat = 0.0
    
    override func sizeThatFits(_ size: CGSize) -> CGSize {
        var sizeThatFits = super.sizeThatFits(size)
        if height > 0.0 {
            sizeThatFits.height = height
            if(isiPhoneXScreen()) {
                sizeThatFits.height = height + 35
            }
        }
        return sizeThatFits
    }
    
    }
    

    then you only have to replace the normal UITabBar for your CustomTabBar class in the storyboard

    enter image description here