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
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)
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()
}
}