Search code examples
iosswiftuitabbarcontrolleruitabbartabbar

Parent TabBar Clips Bottom of Children ViewControllers


I have a tabBarController with a curved tabBar via caShapeLayer.

My issue is the rectangular frame tabBar clips the bottom of children viewControllers.

My goal/hope was to go under and clip the bottom by the curved frame. See image for reference.

enter image description here

Any guidance would be really appreciated.

Code for Curved TabBar in TabBarController

override func viewDidLoad() {
super.viewDidLoad()
    
self.view.backgroundColor = .blue
self.tabBar.backgroundColor = .clear
self.tabBar.barStyle = .default
self.tabBar.isTranslucent = false
self.tabBar.clipsToBounds = false
hideTabBarBorder()
}

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    addTabBarShape()
}

func addTabBarShape() {

let shapeLayer = CAShapeLayer()

let offset:CGFloat = tabBar.bounds.width/3.5
let bounds: CGRect = tabBar.bounds

let rectBounds: CGRect = CGRect(x: bounds.origin.x, y: bounds.origin.y + (bounds.size.height / 2), width: bounds.size.width, height: bounds.size.height / 2)

let rectPath: UIBezierPath = UIBezierPath(rect: rectBounds)
let ovalBounds: CGRect = CGRect(x: bounds.origin.x - (offset / 2), y: bounds.origin.y, width: bounds.size.width + offset, height: bounds.size.height)
let ovalPath: UIBezierPath = UIBezierPath(ovalIn: ovalBounds)
rectPath.append(ovalPath)

shapeLayer.path = rectPath.cgPath
shapeLayer.fillColor = .blue
shapeLayer.shadowPath =  rectPath.cgPath
shapeLayer.shadowColor = UIColor.black.cgColor
shapeLayer.shadowOpacity = 0.1
shapeLayer.shadowRadius = 20
shapeLayer.shadowOffset = CGSize(width: 0, height: -8)

shapeLayer.shouldRasterize = true
shapeLayer.rasterizationScale = UIScreen.main.scale

    if let oldShapeLayer = self.tabBarShapeLayer {
        self.tabBar.layer.replaceSublayer(oldShapeLayer, with: shapeLayer)
    } else {
        self.tabBar.layer.insertSublayer(shapeLayer, at: 0)
    }
    self.tabBarShapeLayer = shapeLayer
}

func hideTabBarBorder() {
    self.tabBar.backgroundImage = UIImage.from(color: Constants.style.darkBlue)
    self.tabBar.shadowImage = UIImage()
}

extension UIImage {
    static func from(color: UIColor) -> UIImage {
    let rect = CGRect(x: 0, y: 0, width: 1, height: 1)
    UIGraphicsBeginImageContext(rect.size)
    let context = UIGraphicsGetCurrentContext()
    context!.setFillColor(color.cgColor)
    context!.fill(rect)
    let img = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return img!
    }
}

Solution

  • My workaround was drawing the curve at a higher y-point than the tabBar frame...