2017-07-14 60 views
1

我寫這個自定義UIView類繪製自定義形狀如何更改UIGraphicsGetCurrentContext的fillColor?

class ShapeView: UIView { 

var color: UIColor? 

init(frame: CGRect, color: UIColor) { 
    super.init(frame: frame) 
    self.color = color 
} 

required init?(coder aDecoder: NSCoder) { 
    fatalError("init(coder:) has not been implemented") 
} 

override func draw(_ rect: CGRect) { 
    super.draw(rect) 
    drawShape(rect: rect, color: self.color!) 
} 

func drawShape(rect: CGRect,color: UIColor) { 
    guard let ctx = UIGraphicsGetCurrentContext() else { return } 
    ctx.setFillColor(UIColor.clear.cgColor) 

    ctx.beginPath() 
    ctx.move(to: CGPoint(x: rect.width/2, y: 0)) 
    ctx.addLine(to: CGPoint(x: rect.width, y: rect.height/2)) 
    ctx.addLine(to: CGPoint(x: rect.width/2 , y: rect.height)) 
    ctx.addLine(to: CGPoint(x: 0, y: rect.height/2)) 


    ctx.closePath() 
    ctx.setFillColor(color.cgColor) 
    ctx.fillPath() 
    ctx.strokePath() 
} 

override func point(inside point: CGPoint, with event: UIEvent?) -> Bool { 
    let path = UIBezierPath(ovalIn: self.frame) 
    return path.contains(point) 
} 

,並在裏面的造型某處按下用戶我需要改變這種形狀的填充顏色,讓我們說黑與此代碼//調試時顏色沒有改變它看起來像我做錯了什麼。

在一些UIViewController類我寫這個方法

class SomeClass: UIViewController { 
    var shape1: ShapeView? 
    var frame: CGRect? 

    override func viewDidLoad() { 
    let x = view.frame.midX 
    let y = view.frame.midY 

    self.frame = CGRect(x: x, y: y, width: 100, height: 100) 
    super.viewDidLoad() 
    self.shape1 = ShapeView(frame: frame!, color: .red) 
    shape1?.backgroundColor = .clear 
    view.addSubview(shape1!) 
} 
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 
    let location = touches.first!.location(in: self.view) 
    if (shape1?.point(inside: location, with: event))! { 
     print("inside shape1") 
     shape1?.drawShape(rect: frame!, color: .black) 
    } else { 
     print("outside shape1") 
     shape1?.drawShape(rect: frame!, color: .red) 
    } 
    } 

任何想法!

+0

當你調用這個'如果(shape1 .point(內:位置,用:事件))!在另一個'ViewController'或在同一個'ShapeView'類 –

+0

'''1'那裏有什麼'shape1'。shape1?.drawShape(rect:frame !, color:.black) } ..它是一個UIView –

回答

2

不要叫你的drawShape()直接FUNC - 它被調用每個對象油漆本身時間:

override func draw(_ rect: CGRect) { 
    super.draw(rect) 
    drawShape(rect: rect, color: self.color!) 
} 

所以,它會立即改變填充顏色回shape1color財產。

相反,做這樣的事情(未測試,只是這裏打字):

if (shape1?.point(inside: location, with: event))! { 
    print("inside shape1") 
    shape1?.color = UIColor.black 
} else { 
    print("outside shape1") 
    shape1?.color = UIColor.red 
} 
shape1?.setNeedsDisplay() 

編輯:您還可以修改您的ShapeView類是這樣的:

var color: UIColor? { 
    didSet { 
     self.setNeedsDisplay() 
    } 
} 

這將消除需要在接觸處理程序中「手動」呼叫.setNeedsDisplay()

編輯#2:您可以粘貼到一個遊樂場網頁,它應該不用改就能運行......在操場頁面運行的結果

import UIKit 
import PlaygroundSupport 

class ShapeView: UIView { 

    var color: UIColor? { 
     didSet { 
      self.setNeedsDisplay() 
     } 
    } 

    init(frame: CGRect, color: UIColor) { 
     super.init(frame: frame) 
     self.color = color 
    } 

    required init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 

    override func draw(_ rect: CGRect) { 
     super.draw(rect) 
     drawShape(rect: rect, color: self.color!) 
    } 

    func drawShape(rect: CGRect,color: UIColor) { 
     guard let ctx = UIGraphicsGetCurrentContext() else { return } 
     ctx.setFillColor(UIColor.clear.cgColor) 

     ctx.beginPath() 
     ctx.move(to: CGPoint(x: rect.width/2, y: 0)) 
     ctx.addLine(to: CGPoint(x: rect.width, y: rect.height/2)) 
     ctx.addLine(to: CGPoint(x: rect.width/2 , y: rect.height)) 
     ctx.addLine(to: CGPoint(x: 0, y: rect.height/2)) 


     ctx.closePath() 
     ctx.setFillColor(color.cgColor) 
     ctx.fillPath() 
     ctx.strokePath() 
    } 

    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool { 
     let path = UIBezierPath(ovalIn: self.frame) 
     return path.contains(point) 
    } 
} 

class VCA : UIViewController { 

    var shape1: ShapeView? 
    var frame: CGRect? 

    override func viewDidLoad() { 
     let x = view.frame.midX 
     let y = view.frame.midY 

     self.frame = CGRect(x: x, y: y, width: 100, height: 100) 
     super.viewDidLoad() 
     self.shape1 = ShapeView(frame: frame!, color: .red) 
     shape1?.backgroundColor = .clear 
     view.addSubview(shape1!) 
    } 

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 
     let location = touches.first!.location(in: self.view) 
     if (shape1?.point(inside: location, with: event))! { 
      print("inside shape1") 
      shape1?.color = UIColor.black 
     } else { 
      print("outside shape1") 
      shape1?.color = UIColor.red 
     } 
    } 

} 

let vcA = VCA() 
vcA.view.backgroundColor = .yellow 
PlaygroundPage.current.liveView = vcA.view 

屏幕記錄:

enter image description here

+0

嗯,不工作。 –

+0

請參閱***編輯#2 *** – DonMag

+0

使用「Show Assistant Editor」按鈕打開時間軸輸出(基本上是一個窗口中的模擬器)。你是什​​麼意思「不工作」?你沒有接觸?你有錯誤嗎? – DonMag

0

嘗試這樣,

import UIKit 
class ShapeView: UIView { 
    override init(frame: CGRect) { 
     super.init(frame: frame) 
    } 

    required init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
    } 

    override func draw(_ rect: CGRect) { 
     super.draw(rect) 
     drawShape(rect: rect) 
    } 

    func drawShape(rect: CGRect) { 
     guard let ctx = UIGraphicsGetCurrentContext() else 
     { return } 
     ctx.setFillColor(UIColor.red.cgColor) 

     ctx.beginPath() 
     ctx.move(to: CGPoint(x: rect.width/2, y: 0)) 
     ctx.addLine(to: CGPoint(x: rect.width, y: rect.height/2)) 
     ctx.addLine(to: CGPoint(x: rect.width/2 , y: rect.height)) 
     ctx.addLine(to: CGPoint(x: 0, y: rect.height/2)) 
     ctx.closePath() 
     ctx.fillPath() 
     ctx.strokePath() 
    } 

    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool { 
     let path = UIBezierPath(ovalIn: self.frame) 
     return path.contains(point) 
    }} 

class SomeClass: UIViewController { 
    var shape1: ShapeView? 
    var frame: CGRect? 

    override func viewDidLoad() { 

     super.viewDidLoad() 
     let x = view.frame.midX 
     let y = view.frame.midY 
     shape1 = ShapeView(frame: CGRect(x: x, y: y, width: 100, height: 100)) 
     view.addSubview(shape1!) 
    } 
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 
     let location = touches.first!.location(in: self.view) 
     if (shape1?.point(inside: location, with: event))! { 
      print("inside shape1") 
      shape1?.backgroundColor = .green 
     } else { 
      print("outside shape1") 
      shape1?.backgroundColor = .black 
     } 
} 
} 
+0

我不需要視圖的背景顏色,我需要用另一種顏色填充視圖內的形狀 –

相關問題