
- 7,813
- 15
- 81
- 165
-
Check https://github.com/kirillgorbushko/HKAnimatedTabBar – hbk Apr 26 '20 at 14:04
-
Another simple example: https://github.com/HappyIosDeveloper/SwiftUIAppWithCustomTabBar – Ahmadreza Apr 17 '22 at 04:57
5 Answers
Based on this answer: https://stackoverflow.com/a/58941827/5753078
Subclass UITabBar like following. This solution takes into account the safeArealayout guides for devices with notch. I find 65 to be a sweet spot height for top rounded tabBar.
@IBDesignable class TabBarWithCorners: UITabBar {
@IBInspectable var color: UIColor?
@IBInspectable var radii: CGFloat = 15.0
private var shapeLayer: CALayer?
override func draw(_ rect: CGRect) {
addShape()
}
private func addShape() {
let shapeLayer = CAShapeLayer()
shapeLayer.path = createPath()
shapeLayer.strokeColor = UIColor.gray.withAlphaComponent(0.1).cgColor
shapeLayer.fillColor = color?.cgColor ?? UIColor.white.cgColor
shapeLayer.lineWidth = 2
shapeLayer.shadowColor = UIColor.black.cgColor
shapeLayer.shadowOffset = CGSize(width: 0 , height: -3);
shapeLayer.shadowOpacity = 0.2
shapeLayer.shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: radii).cgPath
if let oldShapeLayer = self.shapeLayer {
layer.replaceSublayer(oldShapeLayer, with: shapeLayer)
} else {
layer.insertSublayer(shapeLayer, at: 0)
}
self.shapeLayer = shapeLayer
}
private func createPath() -> CGPath {
let path = UIBezierPath(
roundedRect: bounds,
byRoundingCorners: [.topLeft, .topRight],
cornerRadii: CGSize(width: radii, height: 0.0))
return path.cgPath
}
override func layoutSubviews() {
super.layoutSubviews()
self.isTranslucent = true
var tabFrame = self.frame
tabFrame.size.height = 65 + (UIApplication.shared.keyWindow?.safeAreaInsets.bottom ?? CGFloat.zero)
tabFrame.origin.y = self.frame.origin.y + ( self.frame.height - 65 - (UIApplication.shared.keyWindow?.safeAreaInsets.bottom ?? CGFloat.zero))
self.layer.cornerRadius = 20
self.frame = tabFrame
self.items?.forEach({ $0.titlePositionAdjustment = UIOffset(horizontal: 0.0, vertical: -5.0) })
}
}

- 483
- 7
- 18
-
3Great answer! One thing though, even it's not that crucial. That annoying 'key window' warning fix: just replace: `UIApplication.shared.keyWindow?` with: `UIApplication.shared.windows.filter {$0.isKeyWindow}.first?` – nja Oct 01 '20 at 08:25
-
Good answer! But for my case it the area behind the rounded corners are opague and can't see the contents below it. I have to set both self.shadowImage = UIImage() and self.backgroundImage = UIImage() so that the backdrop view created by tabBar automatically becomes fully transparent. Took me 2 days to figure this out, hope this helps someone. – Bruce Dec 11 '20 at 02:21
-
This works great! How would you move the individual images up? The titles move up but are now too close to the icons. – TrevPennington Jan 06 '21 at 15:04
-
This is nice but is not working properly, on the corners is showing some white space. If I try to put some view under the tab bar, it will cover it with some white layer on the corners. Also, it's going a lot upwards. The buttons I had with a bottom constraint with 14-16 pts, now the tab bar is touching them. – Emm Nov 17 '21 at 14:34
I am guessing this is UITabBar
so you can either set rounded corners somewhere in code like this:
layer.cornerRadius = 30
layer.masksToBounds = true
layer.maskedCorners = [.layerMaxXMinYCorner, .layerMinXMinYCorner]
The first controls the rounding and the maskedCorners
specifies to only round top left and top right corners.
Or create subclass and set those properties in init
.

- 1,824
- 4
- 18
- 37
Pretty easy; you create your view
like this:
let theView: UIView = {
let v = UIView()
v.translatesAutoresizingMaskIntoConstraints = false
v.backgroundColor = .white
v.layer.cornerRadius = 30
v.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
return v
}()
You can change cornerRadius
to whatever value you like. The code above gives your view
rounded corners at the top, like in your picture.

- 1,828
- 6
- 40
- 108
The Best Way is to subclass UITabBar class and draw your classic tabBar there with shadows you want to add Here is a nice tutorial for Quick start
Another workaround if you don't need total control you can do it like this
tabBar.layer.masksToBounds = true
tabBar.isTranslucent = true
tabBar.layer.cornerRadius = 10
self.tabBar.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]

- 13,556
- 3
- 32
- 49
Try this
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
let path = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: view.frame.width, height: tabBar.frame.height), cornerRadius: 15)
let mask = CAShapeLayer()
mask.path = path.cgPath
tabBar.layer.mask = mask
}

- 151
- 1
- 6