Swift 函数未在更新视图中绘制圆
Swift function not drawing circle in updated view
我的 View Controller 中有一个步进器,用于更新我的 UIView
中的变量(redd1
、greenn1
、bluee1
)。 drawRect
绘制一个初始圆圈,updateColor
用于在其上绘制一个颜色更新的新圆圈。当我调用 updateColor
时变量会更新,我知道它们会通过,因为当我在 updateColor 中打印出它们的值时,它们是正确的。 updateColor
不会画新的圆。
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);
}
}
正如你所提到的,两者都有它们应有的价值。
根据您的代码片段,您绘制的两个圆圈完全位于同一位置,并且颜色完全相同。他们应该如何区分?当然,当它们具有相同的颜色和相同的位置时,您看不到这两个圆圈。它们被覆盖了。
不要在 drawRect
中调用 addSubview
。仅当您要自己画圆时才使用 drawRect
(例如,通过调用 UIBezierPath
的 stroke
)。或者,如果您要将圆圈添加为子视图(作为视图 layer
的 CAShapeLayer
子层),则完全退出 drawRect
。
但是通过在 updateColor
中调用 addSubview
,您并没有改变颜色,而是每次都添加了另一个子视图。同样,通过在 drawRect
中调用 addSubview
,每次 OS 调用 drawRect
时,您也会在那里添加另一个子视图。例如,我 运行 你的代码,将颜色从黑色更改为红色、绿色、蓝色,并触发 drawRect
再次调用几次,当我查看视图层次结构时在视图调试器中,您可以看到视图层次结构中的所有视图:
这是一种危险的做法,因为这些子视图会随着时间的推移累加起来,占用内存。
如果您要添加子视图,我建议 (a) drawRect
不是添加子视图的正确位置; (b) 如果您决定采用 addSubview
方法,请决定是否可以在添加新子视图之前删除以前的子视图。
就我个人而言,如果我想 drawRect
画不同颜色的圆圈,我会 stroke
UIBezierPath
。例如:
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()
}
}
顺便说一句,您注意到我们可以完全退休 updateColor
。使用上面的代码,如果您设置红色、绿色或蓝色,它将调用 setNeedsDisplay
,这将触发视图自动重绘。
您报告上述方法无效。好吧,我用这段代码试过了:
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)
}
}
而且效果很好:
我的 View Controller 中有一个步进器,用于更新我的 UIView
中的变量(redd1
、greenn1
、bluee1
)。 drawRect
绘制一个初始圆圈,updateColor
用于在其上绘制一个颜色更新的新圆圈。当我调用 updateColor
时变量会更新,我知道它们会通过,因为当我在 updateColor 中打印出它们的值时,它们是正确的。 updateColor
不会画新的圆。
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);
}
}
正如你所提到的,两者都有它们应有的价值。 根据您的代码片段,您绘制的两个圆圈完全位于同一位置,并且颜色完全相同。他们应该如何区分?当然,当它们具有相同的颜色和相同的位置时,您看不到这两个圆圈。它们被覆盖了。
不要在 drawRect
中调用 addSubview
。仅当您要自己画圆时才使用 drawRect
(例如,通过调用 UIBezierPath
的 stroke
)。或者,如果您要将圆圈添加为子视图(作为视图 layer
的 CAShapeLayer
子层),则完全退出 drawRect
。
但是通过在 updateColor
中调用 addSubview
,您并没有改变颜色,而是每次都添加了另一个子视图。同样,通过在 drawRect
中调用 addSubview
,每次 OS 调用 drawRect
时,您也会在那里添加另一个子视图。例如,我 运行 你的代码,将颜色从黑色更改为红色、绿色、蓝色,并触发 drawRect
再次调用几次,当我查看视图层次结构时在视图调试器中,您可以看到视图层次结构中的所有视图:
这是一种危险的做法,因为这些子视图会随着时间的推移累加起来,占用内存。
如果您要添加子视图,我建议 (a) drawRect
不是添加子视图的正确位置; (b) 如果您决定采用 addSubview
方法,请决定是否可以在添加新子视图之前删除以前的子视图。
就我个人而言,如果我想 drawRect
画不同颜色的圆圈,我会 stroke
UIBezierPath
。例如:
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()
}
}
顺便说一句,您注意到我们可以完全退休 updateColor
。使用上面的代码,如果您设置红色、绿色或蓝色,它将调用 setNeedsDisplay
,这将触发视图自动重绘。
您报告上述方法无效。好吧,我用这段代码试过了:
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)
}
}
而且效果很好: