2

I'm trying to use my own UITabBar instance inside a UITabBarController. Using Storyboard I know that you can add your Custom Class to your TabbarController using the following:

enter image description here

How can I achieve the same thing programmatically?

Here's my custom class:

I've tried modifying and overriding the tabBar variable inside UITabBarController but it seems that it's a get only variable and can not be modified. Is there an easy solution to fix this issue?

Much appreciated!

class CustomTabBar: UITabBar {
    private var shapeLayer: CALayer?

    private func addShape() {
        let shapeLayer = CAShapeLayer()
        shapeLayer.path = createPath()
        shapeLayer.strokeColor = UIColor.lightGray.cgColor
        shapeLayer.fillColor = UIColor.white.cgColor
        shapeLayer.lineWidth = 1.0

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

        self.shapeLayer = shapeLayer
    }

    override func draw(_ rect: CGRect) {
        self.addShape()
    }

    func createPath() -> CGPath {

        let height: CGFloat = 37.0
        let path = UIBezierPath()
        let centerWidth = self.frame.width / 2

        path.move(to: CGPoint(x: 0, y: 0)) // start top left
        path.addLine(to: CGPoint(x: (centerWidth - height * 2), y: 0)) // the beginning of the trough
        // first curve down
        path.addCurve(to: CGPoint(x: centerWidth, y: height),
                      controlPoint1: CGPoint(x: (centerWidth - 30), y: 0), controlPoint2: CGPoint(x: centerWidth - 35, y: height))
        // second curve up
        path.addCurve(to: CGPoint(x: (centerWidth + height * 2), y: 0),
                      controlPoint1: CGPoint(x: centerWidth + 35, y: height), controlPoint2: CGPoint(x: (centerWidth + 30), y: 0))

        // complete the rect
        path.addLine(to: CGPoint(x: self.frame.width, y: 0))
        path.addLine(to: CGPoint(x: self.frame.width, y: self.frame.height))
        path.addLine(to: CGPoint(x: 0, y: self.frame.height))
        path.close()

        return path.cgPath
    }

    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
        let buttonRadius: CGFloat = 35
        return abs(self.center.x - point.x) > buttonRadius || abs(point.y) > buttonRadius
    }

    func createPathCircle() -> CGPath {

        let radius: CGFloat = 37.0
        let path = UIBezierPath()
        let centerWidth = self.frame.width / 2

        path.move(to: CGPoint(x: 0, y: 0))
        path.addLine(to: CGPoint(x: (centerWidth - radius * 2), y: 0))
        path.addArc(withCenter: CGPoint(x: centerWidth, y: 0), radius: radius, startAngle: CGFloat(180).degreesToRadians, endAngle: CGFloat(0).degreesToRadians, clockwise: false)
        path.addLine(to: CGPoint(x: self.frame.width, y: 0))
        path.addLine(to: CGPoint(x: self.frame.width, y: self.frame.height))
        path.addLine(to: CGPoint(x: 0, y: self.frame.height))
        path.close()
        return path.cgPath
    }
}

And here's my view controller:

final class TabbarViewController: UITabBarController {    
    // MARK: - Properties
    private lazy var tabBarItemControllers: [UIViewController] = {
        let editorController = ...

        let settingsController = ...

        return [editorController, settingsController]
    }()

    // MARK: - Lifecycle
    override func viewDidLoad() {
        super.viewDidLoad()

        configureTabbar()
        setViewControllers(tabBarItemControllers, animated: true)
    }
}
rmaddy
  • 314,917
  • 42
  • 532
  • 579
Yagiz
  • 1,033
  • 2
  • 21
  • 47
  • Check [this](https://stackoverflow.com/questions/47557351/how-can-i-substitute-the-uitabbar-of-uitabbarcontroller-programmatically) – Kamran Jun 03 '19 at 07:34
  • I've noted on my question that this solution didn't work for me. – Yagiz Jun 03 '19 at 10:31
  • Just `override` tabbar as per link provided by @Kamran – VRAwesome Jun 03 '19 at 11:31
  • I am not using any storyboards and xibs , but I also want to have same UITabbar with Shape I tried override and called addShape from init method it is not working @Yagiz did you solve? – AppleBee Oct 16 '19 at 15:28
  • Hi, I have the same issue with custom Tabbar in UITabbarController, I overrided the default Tabbar but I get only a Tabbar that didn't work – Walid Sassi Jan 25 '20 at 12:57

0 Answers0