如何更改 UIGraphicsGetCurrentContext 的 fillColor?
How to change fillColor of UIGraphicsGetCurrentContext?
我写了这个自定义 UIView class 来绘制自定义形状
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我写了这个方法
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)
}
}
任何想法!
不要直接调用您的 drawShape()
func - 每次对象绘制自身时都会调用它:
override func draw(_ rect: CGRect) {
super.draw(rect)
drawShape(rect: rect, color: self.color!)
}
因此,它会立即将填充颜色更改回 shape1
的 color
属性。
相反,做这样的事情(未经测试,只需在此处输入):
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
class:
var color: UIColor? {
didSet {
self.setNeedsDisplay()
}
}
这将消除 "manually" 在您的触摸处理程序中调用 .setNeedsDisplay()
的需要。
编辑 #2: 您可以将其粘贴到 Playground 页面中,它应该 运行 无需更改...
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
Screen-Recording 结果 运行 在 playground 页面中:
这样试试,
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
}
}
}
我写了这个自定义 UIView class 来绘制自定义形状
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我写了这个方法
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)
}
}
任何想法!
不要直接调用您的 drawShape()
func - 每次对象绘制自身时都会调用它:
override func draw(_ rect: CGRect) {
super.draw(rect)
drawShape(rect: rect, color: self.color!)
}
因此,它会立即将填充颜色更改回 shape1
的 color
属性。
相反,做这样的事情(未经测试,只需在此处输入):
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
class:
var color: UIColor? {
didSet {
self.setNeedsDisplay()
}
}
这将消除 "manually" 在您的触摸处理程序中调用 .setNeedsDisplay()
的需要。
编辑 #2: 您可以将其粘贴到 Playground 页面中,它应该 运行 无需更改...
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
Screen-Recording 结果 运行 在 playground 页面中:
这样试试,
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
}
}
}