自定义 UIView 中的无效上下文 0x0 - 后续问题
invalid context 0x0 within custom UIView - follow-up question
这个post:
...应该给我解决问题的关键,但我无法避免无效上下文错误。一些澄清将不胜感激。
我想在 ViewController 加载时显示的子视图中画线。为此,我为 UIView 创建了一个子类,它类似于由 StartPlayer 编辑的 SplitCircleView post。
到运行代码,创建一个新项目并将ViewController文件的内容替换为:
import UIKit
@IBDesignable
class ViewController: UIViewController {
let mySubViewInstance = SplitCircleView()
override func viewDidLoad() {
super.viewDidLoad()
//let mySubViewInstance = SplitCircleView()
mySubViewInstance.setNeedsDisplay(mySubViewInstance.frame)
}
}
class SplitCircleView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
//self.setNeedsDisplay()
//draw(frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
//self.setNeedsDisplay()
//draw(frame)
}
override func setNeedsDisplay(_ rect: CGRect) {
self.backgroundColor = .clear
drawSlice(rect: rect, startPercent: 87.5, endPercent: 37.5, color: .green)
drawSlice(rect: rect, startPercent: 37.5, endPercent: 87.5, color: .red)
}
func drawSlice(rect: CGRect, startPercent: CGFloat, endPercent: CGFloat, color: UIColor) {
let center = CGPoint(x: rect.origin.x + rect.width / 2, y: rect.origin.y + rect.height / 2)
let radius = (min(rect.width, rect.height) / 2)
let startAngle = startPercent / 100 * .pi * 2 - .pi
let endAngle = endPercent / 100 * .pi * 2 - .pi
let path = UIBezierPath()
path.move(to: center)
path.addArc(withCenter: center, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: true)
path.close()
color.setFill()
path.fill()
}
}
如何避免无效上下文错误并在 ViewController 加载时在子视图中绘制内容?
您应该覆盖 draw
,而不是 setNeedsDisplay
。
override func draw(_ rect: CGRect) {
self.backgroundColor = .clear
drawSlice(rect: rect, startPercent: 87.5, endPercent: 37.5, color: .green)
drawSlice(rect: rect, startPercent: 37.5, endPercent: 87.5, color: .red)
}
而且背景颜色的设置只需要设置一次,所以 draw
并不是该行的理想位置。将其移动到 init
.
setNeedsDisplay
表示绘图需要更新。但实际绘制的是draw
。
有两个地方需要修改。
您正在创建一个新视图,因此您需要添加到 viewController
的视图
override func viewDidLoad() {
super.viewDidLoad()
let mySubViewInstance = SplitCircleView.init(frame: self.view.bounds)
self.view.addSubview(mySubViewInstance)
// mySubViewInstance.setNeedsDisplay(mySubViewInstance.frame)
}
第二个是绘制函数不使用 setNeedsDisplay();
override func draw(_ rect: CGRect) {
self.backgroundColor = .clear
drawSlice(rect: rect, startPercent: 87.5, endPercent: 37.5, color: .green)
drawSlice(rect: rect, startPercent: 37.5, endPercent: 87.5, color: .red)
}
这样,你的美图就在这里。
这个post:
我想在 ViewController 加载时显示的子视图中画线。为此,我为 UIView 创建了一个子类,它类似于由 StartPlayer 编辑的 SplitCircleView post。
到运行代码,创建一个新项目并将ViewController文件的内容替换为:
import UIKit
@IBDesignable
class ViewController: UIViewController {
let mySubViewInstance = SplitCircleView()
override func viewDidLoad() {
super.viewDidLoad()
//let mySubViewInstance = SplitCircleView()
mySubViewInstance.setNeedsDisplay(mySubViewInstance.frame)
}
}
class SplitCircleView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
//self.setNeedsDisplay()
//draw(frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
//self.setNeedsDisplay()
//draw(frame)
}
override func setNeedsDisplay(_ rect: CGRect) {
self.backgroundColor = .clear
drawSlice(rect: rect, startPercent: 87.5, endPercent: 37.5, color: .green)
drawSlice(rect: rect, startPercent: 37.5, endPercent: 87.5, color: .red)
}
func drawSlice(rect: CGRect, startPercent: CGFloat, endPercent: CGFloat, color: UIColor) {
let center = CGPoint(x: rect.origin.x + rect.width / 2, y: rect.origin.y + rect.height / 2)
let radius = (min(rect.width, rect.height) / 2)
let startAngle = startPercent / 100 * .pi * 2 - .pi
let endAngle = endPercent / 100 * .pi * 2 - .pi
let path = UIBezierPath()
path.move(to: center)
path.addArc(withCenter: center, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: true)
path.close()
color.setFill()
path.fill()
}
}
如何避免无效上下文错误并在 ViewController 加载时在子视图中绘制内容?
您应该覆盖 draw
,而不是 setNeedsDisplay
。
override func draw(_ rect: CGRect) {
self.backgroundColor = .clear
drawSlice(rect: rect, startPercent: 87.5, endPercent: 37.5, color: .green)
drawSlice(rect: rect, startPercent: 37.5, endPercent: 87.5, color: .red)
}
而且背景颜色的设置只需要设置一次,所以 draw
并不是该行的理想位置。将其移动到 init
.
setNeedsDisplay
表示绘图需要更新。但实际绘制的是draw
。
有两个地方需要修改。
您正在创建一个新视图,因此您需要添加到 viewController
的视图 override func viewDidLoad() {
super.viewDidLoad()
let mySubViewInstance = SplitCircleView.init(frame: self.view.bounds)
self.view.addSubview(mySubViewInstance)
// mySubViewInstance.setNeedsDisplay(mySubViewInstance.frame)
}
第二个是绘制函数不使用 setNeedsDisplay();
override func draw(_ rect: CGRect) {
self.backgroundColor = .clear
drawSlice(rect: rect, startPercent: 87.5, endPercent: 37.5, color: .green)
drawSlice(rect: rect, startPercent: 37.5, endPercent: 87.5, color: .red)
}
这样,你的美图就在这里。