Home > Software design >  UIView.draw(rect:) is called but not drawing its graphic context
UIView.draw(rect:) is called but not drawing its graphic context

Time:01-17

I'm fairly new to ios programming

I try to draw some arcs for my circular progress bar in UIView.draw(rect:) method. I'm using UIGraphicsGetCurrentContext to get the context and add arc path and draw in the method of custom UIView called MyProgressView

So I made an object of my custom view and it worked fine But if I make a couple of more objects, they don't work

UIView.draw(rect:) is called every time whenever it needs to be. the first one is drawing properly and the rest are not


class MyProgressView: UIView {
    
    var startAngle: Double = 0.0
    var endAngle: Double = 0.0 {
        didSet{
            self.setNeedsDisplay()
        }
    }
    
    
    func radian(_ degree: Double) -> Double {
        return (degree - 90) * Double.pi / 180.0
    }
        
    override func draw(_ rect: CGRect) {
        guard let context = UIGraphicsGetCurrentContext() else { return }
        context.setLineWidth(10)
        context.setStrokeColor(UIColor.white.cgColor)
        context.addArc(center: self.center, radius: 30, startAngle: radian(startAngle), endAngle: radian(endAngle), clockwise: false)
        context.strokePath()
        
    }
}

I put self.setNeedsDisplay() in didSet of a variable called endAngle

and inside of view controller's viewDidLoad,

let progressBar = MyProgressView()
progressBar.frame = CGRect(x: 0, y: 0, width: view.frame.width / 2, height:view.frame.height / 2)
progressBar.backgroundColor = .systemMint
progressBar.startAngle = 0
progressBar.endAngle = 180
view.addSubview(progressBar)

and it looks fine

enter image description here

but if I add two more, they don't work


let progressBar2 = MyProgressView()
progressBar2.frame = CGRect(x: 150, y: 0, width: view.frame.width / 2, height: view.frame.height / 2)
progressBar2.backgroundColor = .systemPink
progressBar2.startAngle = 90
progressBar2.endAngle = 270
view.addSubview(progressBar2)


let progressBar3 = MyProgressView()

progressBar3.frame = CGRect(x: 0, y: 150, width: view.frame.width / 2, height: view.frame.height / 2)
progressBar3.backgroundColor = .systemIndigo
progressBar3.startAngle = 90
progressBar3.endAngle = 270
view.addSubview(progressBar3)

enter image description here

Can anybody explain what's missing here?

I made it and run in playground, iOS version is 15.4

Thanks

CodePudding user response:

You have 2 problems

1- The method that converts to radians isn't correct

2- You need to use a zero based center point

class MyProgressView: UIView {
    var startAngle: Double = 0.0
    var endAngle: Double = 0.0
    func radian(_ number: Double) -> CGFloat {
        return CGFloat(number * .pi / 180)
    } 
    override func draw(_ rect: CGRect) {
        guard let context = UIGraphicsGetCurrentContext() else { return }
        context.setLineWidth(10)
        context.setStrokeColor(UIColor.white.cgColor)
        context.addArc(center: CGPoint(x:rect.size.width / 2, y:rect.size.height / 2), radius: 30, startAngle: radian(startAngle), endAngle: radian(endAngle), clockwise: false)
        context.strokePath()
    }
}

Full demo

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        let progressBar = MyProgressView()
        progressBar.frame = CGRect(x: 0, y: 0, width: view.frame.width / 2, height:view.frame.height / 2)
        progressBar.backgroundColor = .systemMint
        progressBar.startAngle = 0
        progressBar.endAngle = 180
        view.addSubview(progressBar)

        let progressBar2 = MyProgressView()
        progressBar2.frame = CGRect(x: 150, y: 0, width: view.frame.width / 2, height: view.frame.height / 2)
        progressBar2.backgroundColor = .systemPink
        progressBar2.startAngle = 90
        progressBar2.endAngle = 270
        view.addSubview(progressBar2)
 
        let progressBar3 = MyProgressView() 
        progressBar3.frame = CGRect(x: 0, y: 300, width: view.frame.width / 2, height: view.frame.height / 2)
        progressBar3.backgroundColor = .systemIndigo
        progressBar3.startAngle = 90
        progressBar3.endAngle = 270
        view.addSubview(progressBar3)
 
    }
 
}

class MyProgressView: UIView {
    var startAngle: Double = 0.0
    var endAngle: Double = 0.0
    func radian(_ number: Double) -> CGFloat {
        return CGFloat(number * .pi / 180)
    }
    override func draw(_ rect: CGRect) {
        guard let context = UIGraphicsGetCurrentContext() else { return }
        context.setLineWidth(10)
        context.setStrokeColor(UIColor.white.cgColor)
        context.addArc(center: CGPoint(x:rect.size.width / 2, y:rect.size.height / 2), radius: 30, startAngle: radian(startAngle), endAngle: radian(endAngle), clockwise: false)
        context.strokePath()
    }
}

enter image description here

  • Related