2016-01-30 84 views
1

我的視圖控制器中有一個步進器,用於更新我的UIView中的變量(redd1,greenn1,bluee1)。 drawRect繪製一個初始圓,updateColor意味着在其上繪製一個新的圓,並帶有更新的顏色。當我調用updateColor時變量會更新,我知道它們會通過,因爲當我將它們的值打印在updateColor中時,它們是正確的。 updateColor不會畫一個新的圓圈。在更新視圖中不能繪製圓圈的swift函數

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); 
    } 
} 
+0

所以CIRCLE2被添加到您的視圖和圈子不會被添加到您的看法? – Anokrize

+0

是的,我知道它不在它後面,因爲我把圈子2拿出來,以確保 – Steve

回答

2

不要在drawRect內撥打addSubview。如果您要自己畫一個圓圈(例如通過撥打strokeUIBezierPath),請僅使用drawRect。或者,如果您打算將圓圈添加爲子視圖(如CAShapeLayer子圖層到視圖的layer),則退回drawRect

但通過調用updateColoraddSubview,你不改變顏色,而是你每次增加一個子視圖。同樣,通過在drawRect中調用addSubview,您也會在其中添加另一個子視圖,每次操作系統調用drawRect時。例如,我運行了代碼,將顏色從黑色更改爲紅色,綠色更改爲藍色,並且觸發drawRect再次被調用幾次,當我查看視圖調試器中的視圖層次結構時,可以看到所有的視圖層次結構中的觀點:

enter image description here

這是一種危險的做法,因爲這些子視圖將增加隨着時間的推移,佔用內存。

如果你要添加子視圖,我會建議(a)drawRect是不適合添加子視圖的地方;和(b)如果您決定採用addSubview的方法,請決定是否可以在添加新的子視圖之前刪除先前的子視圖。

就個人而言,如果我想drawRect畫不同顏色的圓圈,我只會strokeUIBezierPath。例如:

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

它工作得很好:

enter image description here

+0

它也停止畫第一個圓,當我不使用drawRect – Steve

+0

如果你要自己畫,使用' drawRect'(請參閱我的答案中的代碼片段作爲示例)。如果你打算使用子視圖方法,(a)不要使用'drawRect'; (b)在'awakeFromNIB'或類似的東西中進行初始設置;和(c)當你更新顏色時,刪除舊的子視圖並添加一個新的子視圖。 – Rob

+0

我用你的代碼,它創建了圓形,但現在函數不能識別紅色,綠色和藍色的值何時由我的視圖控制器中的步進器更改。 – Steve

0

正如你所提到的,兩者都有他們應該有的價值。 您正在繪製的兩個圓圈完全位於同一位置,根據您的代碼片段,它們的顏色完全相同。他們應該如何區別?當然,當他們具有相同的顏色和相同的位置時,你看不到這兩個圓圈。他們被覆蓋。

+0

圈子是假設用變量創建的新顏色在圓圈2的頂部。我知道它不只是在下面,因爲我把圓圈2取出,它仍然沒有出現 – Steve