Search code examples
iosswiftswiftuitabbar

Curved bottom bar


I want to make curved bottom bar it is not looking perfect round by below code

struct customShape: Shape {
    
    var xAxis : CGFloat
    
    var animatableData: CGFloat{
        get { return xAxis}
        set { xAxis = newValue}
    }
    func path(in rect: CGRect) -> Path {
        
        return Path { path in
            
            path.move(to: CGPoint(x: 0, y: 0))
            path.addLine(to: CGPoint(x: rect.width, y: 0))
            path.addLine(to: CGPoint(x: rect.width, y: rect.height))
            path.addLine(to: CGPoint(x: 0, y: rect.height))
            
            let center = xAxis
            
            path.move(to: CGPoint(x: center - 43, y: 0))
            
            let to1 = CGPoint(x: center, y: 50)
            let center1 = CGPoint(x: center - 30, y: 0)
            let center2 = CGPoint(x: center - 46, y: 42)
            
            let to2 = CGPoint(x: center + 52, y: 0)
            let center3 = CGPoint(x: center + 57, y: 47)
            let center4 = CGPoint(x: center + 35, y: 0)
            
            path.addCurve(to: to1, control1: center1, control2: center2)
            path.addCurve(to: to2, control1: center3, control2: center4)
         
        }
        
    }
    
}


Solution

  • You are trying to construct a circle with Bezier handles. And it seems you are not calculating the values but guessing and trying. This will be at least very hard if not impossible to solve. Try to add an arc instead of a curve.

    Possible implementation:

    struct customShape: Shape {
        
        var xAxis : CGFloat
        var radius: CGFloat = 40
        
        var animatableData: CGFloat{
            get { return xAxis}
            set { xAxis = newValue}
        }
        func path(in rect: CGRect) -> Path {
            
            return Path { path in
    
                path.move(to: CGPoint(x: 0, y: 0))
                // add a line to the starting point of the circle
                path.addLine(to: CGPoint(x: xAxis - radius, y: 0))
                
                // add the arc with the centerpoint of (xAxis,0) and 180°
                path.addArc(center: .init(x: xAxis, y: 0), radius: radius, startAngle: .init(degrees: 180), endAngle: .init(degrees: 0), clockwise: true)
    
                // complete the rectangle
                path.addLine(to: .init(x: rect.size.width, y: 0))
                path.addLine(to: CGPoint(x: rect.width, y: rect.height))
                path.addLine(to: CGPoint(x: 0, y: rect.height))
                path.closeSubpath()
            }
        }
    }
    

    Output