iosswiftuibezierpath

Chart with UIBezierPath at one below one


I am trying to make pie chart as below which is working fine but I have issue with end path (which is orange in below image).

enter image description here

What I want to do is make end of orange shape to below the green one so that I can achieve as below.

enter image description here

Any suggestion how this can be done?

Code can be found at below link.

https://drive.google.com/file/d/1ST0zNooLgRaI8s2pDK3NMjBQYjBSRoXB/view?usp=sharing

Below is what I have.

func drawBeizer(start_angle : CGFloat, end_angle : CGFloat, final_color : UIColor) {
    let path1 : UIBezierPath = UIBezierPath()
    
    path1.addArc(withCenter: CGPoint(x: self.frame.size.width/2, y: self.frame.size.height/2), radius: ((self.frame.size.width-main_view_width)/2), startAngle: start_angle, endAngle: end_angle, clockwise: true)
    path1.lineWidth = main_view_width
    path1.lineCapStyle = .round
    final_color.setStroke()
    path1.stroke()
    
}

This function I am passing start angle and end angle & color for the path.


Solution

  • I found a way to do this. Below is the full code.

    I am adding other addArc using end angles.

    ViewController.swift

    import UIKit
    
    class ViewController: UIViewController {
    
        @IBOutlet weak var myView: MyView!
        
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view.
            
            myView.setupData(inner_color: [.green, .purple, .blue, .orange], inner_view_width: self.view.frame.width/5.0, inner_angle: [0.0, 90.0, 180.0, 270.0])
            
            myView.backgroundColor = UIColor.white
    
        }
        
    }
    

    MyView.swift

    import UIKit
    
    class MyView: UIView {
        
        var main_radius : CGFloat = 0.0
        
        var main_color : [UIColor] = [UIColor.black, UIColor.green]
        
        var main_view_width : CGFloat = 1.0
        
        var main_angle : [CGFloat] = [-CGFloat.pi, 0.0]
        var actual_angle : [CGFloat] = []
        
        func setupData(inner_color : [UIColor], inner_view_width : CGFloat, inner_angle : [CGFloat]) {
            main_color = inner_color
            
            main_view_width = inner_view_width
            
            main_angle = inner_angle
            
            actual_angle = inner_angle
            
            var temp_main_angle : [CGFloat] = []
            for i in 0..<main_angle.count {
                temp_main_angle.append(main_angle[i]*Double.pi/180)
            }
            main_angle = temp_main_angle
            
            draw(CGRect(x: 0, y: 0, width: self.frame.size.width, height: self.frame.size.width))
        }
        
        override func draw(_ rect: CGRect) {
            
            if (main_color.count >= 2) {
                
                var inner_position : Int = 0
                
                // first draw with sharp corner
                for i in 0..<main_color.count {
                    
                    if (i == (main_color.count-1)) {
                        inner_position = 0
                    } else {
                        inner_position = i+1
                    }
                    
                    drawBeizer(start_angle: main_angle[i], end_angle: main_angle[inner_position], final_color: main_color[i])
                }
                
                
                // append with ending icons for circle
                for i in 0..<main_color.count {
                    
                    if (i == (main_color.count-1)) {
                        inner_position = 0
                    } else {
                        inner_position = i+1
                    }
                    
                    drawBeizer(start_angle: main_angle[inner_position], end_angle: main_angle[inner_position]+(1*Double.pi/180), final_color: main_color[i], withCircle: true) // make here final_color as .black to see what I am doing with this loop
                }
            }
        }
        
        func drawBeizer(start_angle : CGFloat, end_angle : CGFloat, final_color : UIColor, withCircle: Bool = false) {
            let path1 : UIBezierPath = UIBezierPath()
            
            path1.addArc(withCenter: CGPoint(x: self.frame.size.width/2, y: self.frame.size.height/2), radius: ((self.frame.size.width-main_view_width)/2), startAngle: start_angle, endAngle: end_angle, clockwise: true)
            path1.lineWidth = main_view_width
            if (withCircle) {
                path1.lineCapStyle = .round
            }
            final_color.setStroke()
            path1.stroke()
            
        }
    }
    

    Full code here

    enter image description here enter image description here