Reputation: 1153
I have a stepper in my View Controller that updates variables(redd1
, greenn1
, bluee1
) in my UIView
. drawRect
draws an initial circle and updateColor
is meant to draw a new circle on top of it with an updated color. The variables get updated when I call updateColor
and I know that they get passed through because when i have their values printed out in updateColor they are correct. updateColor
won't draw a new circle.
class UIView1: UIView {
var redd1 = 0.0;
var greenn1 = 0.0;
var bluee1 = 0.0;
override init(frame: CGRect)
{
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder)
{
super.init(coder: aDecoder)
}
override func drawRect(rect: CGRect)
{
let circle2 = UIView(frame: CGRect(x: -25.0, y: 10.0, width: 100.0, height:100.0))
circle2.layer.cornerRadius = 50.0
let startingColor2 = UIColor(red: (CGFloat(redd1))/255, green: (CGFloat (greenn1))/255, blue: (CGFloat(bluee1))/255, alpha: 1.0)
circle2.backgroundColor = startingColor2;
addSubview(circle2);
}
func updateColor()
{
let circle = UIView(frame: CGRect(x: -25.0, y: 10.0, width: 100.0, height: 100.0))
circle.layer.cornerRadius = 50.0;
let startingColor = UIColor(red: (CGFloat(redd1))/255, green: (CGFloat(greenn1))/255, blue: (CGFloat(bluee1))/255, alpha: 1.0)
circle.backgroundColor = startingColor;
addSubview(circle);
}
}
Upvotes: 1
Views: 719
Reputation: 437392
Do not call addSubview
in drawRect
. Only use drawRect
if you were going to draw a circle yourself (e.g. by calling stroke
of a UIBezierPath
). Or if you're going to add circles as subviews (as CAShapeLayer
sublayers to the view's layer
), the retire drawRect
altogether.
But by calling addSubview
in updateColor
, you're not changing the color, but rather you're adding another subview every time. Likewise, by calling addSubview
in drawRect
, you're adding another subview there, too, every time the OS calls drawRect
. For example, I ran your code, changing the color from black to red, to green, to blue, and triggered drawRect
to be called again a few more times, and when I look at the view hierarchy in the view debugger, you can see all of the views in the view hierarchy:
This is a dangerous practice, because those subviews will add up over time, taking up memory.
If you're going to add subviews, I would suggest (a) drawRect
is not the right place to be adding subviews; and (b) if you're determined to go the addSubview
approach, decide whether you can remove the previous subviews before adding new ones.
Personally, if I wanted drawRect
to draw circles of different colors, I would just stroke
the UIBezierPath
. For example:
class CircleView: UIView {
var redd1: CGFloat = 0.0 {
didSet {
setNeedsDisplay()
}
}
var greenn1 : CGFloat = 0.0 {
didSet {
setNeedsDisplay()
}
}
var bluee1: CGFloat = 0.0 {
didSet {
setNeedsDisplay()
}
}
override func drawRect(rect: CGRect) {
let color = UIColor(red: redd1 / 255.0, green: greenn1 / 255.0, blue: bluee1 / 255.0, alpha: 1.0)
color.setStroke()
let path = UIBezierPath(arcCenter: CGPoint(x: 75, y: 75), radius: 50, startAngle: 0, endAngle: CGFloat(M_PI * 2.0), clockwise: true)
path.lineWidth = 2
path.lineCapStyle = .Round
path.stroke()
}
}
By the way, you notice that we can retire updateColor
entirely. With the above code, if you set either red, green, or blue, it will call setNeedsDisplay
, which will trigger the view being redrawn automatically.
You report that the above isn't working. Well, I tried it with this code:
class ViewController: UIViewController {
@IBOutlet weak var circleView: CircleView!
@IBOutlet weak var redSlider: UISlider!
@IBOutlet weak var greenSlider: UISlider!
@IBOutlet weak var blueSlider: UISlider!
override func viewDidLoad() {
super.viewDidLoad()
redSlider.value = Float(circleView.redd1) / 255.0
greenSlider.value = Float(circleView.greenn1) / 255.0
blueSlider.value = Float(circleView.bluee1) / 255.0
}
@IBAction func valueChangedForSlider(sender: UISlider) {
circleView.redd1 = 255.0 * CGFloat(redSlider.value)
circleView.greenn1 = 255.0 * CGFloat(greenSlider.value)
circleView.bluee1 = 255.0 * CGFloat(blueSlider.value)
}
}
And it worked fine:
Upvotes: 2
Reputation: 6746
As you mentioned that the both have the values which they should have. The two circles which you are drawing are exactly on the same postion and both have exactly the same color according to your code snippet. How should they differ? Of course you can't see the two circles when they are having the same color and same position. They are overlayed.
Upvotes: 0