1

I'm workin on an iOS app which require a curve under UITabBarItem as showing here

I followed some tutorials and I capable to reach this code which make my UITabBar curved,

import Foundation
import  UIKit
class AppTabBar: UITabBar {
    var curvePos : CGFloat =  0
    private var shapeLayer: CALayer?
    override func draw(_ rect: CGRect) {
        curvePos = rect.width / 2
        self.addShape(rect: rect)
    }
    
    private func addShape(rect: CGRect) {
        let shapeLayer = CAShapeLayer()
        shapeLayer.path = createPath(in: rect)
        shapeLayer.strokeColor = UIColor.lightGray.cgColor
        shapeLayer.fillColor = #colorLiteral(red: 0.9782002568, green: 0.9782230258, blue: 0.9782107472, alpha: 1)
        shapeLayer.lineWidth = 0.5
        shapeLayer.shadowOffset = CGSize(width:0, height:0)
        shapeLayer.shadowRadius = 10
        shapeLayer.shadowColor = UIColor.gray.cgColor
        shapeLayer.shadowOpacity = 0.3
        if let oldShapeLayer = self.shapeLayer {
            self.layer.replaceSublayer(oldShapeLayer, with: shapeLayer)
        } else {
            self.layer.insertSublayer(shapeLayer, at: 0)
        }
        self.shapeLayer = shapeLayer
    }

    func createPath(in rect: CGRect) -> CGPath {
        let path = UIBezierPath()
        path.move(to: CGPoint(x: 0, y: 0))
        path.addLine(to: CGPoint(x: 0, y: rect.height))
        path.addLine(to: CGPoint(x: rect.width, y: rect.height))
        path.addLine(to: CGPoint(x: rect.width, y: 0))
        // adding Curve...
        path.move(to: CGPoint(x: curvePos + 40, y: 0))
        path.addQuadCurve(to: CGPoint(x: curvePos - 40, y: 0), controlPoint: CGPoint(x: curvePos, y: 70))
        return path.cgPath
    }
}

what I need now: 1-How can I change curvePos value when tapping each item of UITabBar to make curve under selected Item. 2- How can I animating UITabBarItem or UITabBarItem image to make it as showing in above image. Any help will be appreciated.

Ali A. Jalil
  • 873
  • 11
  • 25
  • Here are some other questions that may help you https://stackoverflow.com/questions/55042538/how-to-set-top-left-and-right-corner-radius-with-desired-drop-shadow-in-uitabbar https://stackoverflow.com/questions/62730824/making-bends-and-curves-in-the-tab-bar-using-swift – Donald Timberlake Feb 11 '21 at 12:45

2 Answers2

0

enter image description here

import UIKit

class MainViewController: UIViewController, UITabBarDelegate {
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
        
        
        switch item.title! {
        case "Home":
            //let oldShapeLayer = CAShapeLayer()
            //let shapeLayer = CAShapeLayer()
            //tabBar.layer.replaceSublayer(oldShapeLayer, with: shapeLayer)
            break
            
        case "Gallery" :
            
            break
            
        case "Settings" :
            
            break
            
        default: break
            
        }
        
    }
    
}
0

After many trying I could get what I would like to do: Bellow modified code of my AppTabBar:

class AppTabBar: UITabBar {
    var curvePos : CGFloat =  0
    private var shapeLayer: CALayer?
    override func draw(_ rect: CGRect) {
        let itemIndex = CGFloat(self.items!.firstIndex(of: selectedItem!)!)
        let itemWidth = self.frame.width / CGFloat(self.items!.count)
        curvePos = (itemWidth / 2) + (itemWidth * itemIndex)
        self.addShape(rect: rect)
    }

    private func addShape(rect: CGRect) {
        let shapeLayer = CAShapeLayer()
        shapeLayer.path = createPath(in: rect)
        shapeLayer.strokeColor = UIColor.lightGray.cgColor
        shapeLayer.fillColor = #colorLiteral(red: 0.9782002568, green: 0.9782230258, blue: 0.9782107472, alpha: 1)
        shapeLayer.lineWidth = 0.5
        shapeLayer.shadowOffset = CGSize(width:0, height:0)
        shapeLayer.shadowRadius = 10
        shapeLayer.shadowColor = UIColor.gray.cgColor
        shapeLayer.shadowOpacity = 0.3

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

    func createPath(in rect: CGRect) -> CGPath {
        let path = UIBezierPath()
        path.move(to: CGPoint(x: 0, y: 0))
        path.addLine(to: CGPoint(x: 0, y: rect.height))
        path.addLine(to: CGPoint(x: rect.width, y: rect.height))
        path.addLine(to: CGPoint(x: rect.width, y: 0))
        
        // adding Curve...
        path.move(to: CGPoint(x: curvePos + 40, y: 0))
        
        path.addQuadCurve(to: CGPoint(x: curvePos - 40, y: 0), controlPoint: CGPoint(x: curvePos, y: 70))
        return path.cgPath
    }
}

and creating another class for UITabBarController as bellow:

class CustomTabBarController:  UITabBarController, UITabBarControllerDelegate    {
    override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
       print("sssss")
        tabBar.setNeedsDisplay()
    }
}

set CustomTabBarController for TabBarController and AppTabBar for UITabBar

Ali A. Jalil
  • 873
  • 11
  • 25