我正在尝试通过扩展可以在自定义视图的中心显示圆的类来创建自定义视图。为了添加自定义图形,我覆盖绘图(_ rect:cgrect(方法如下。
public override func draw(_ rect: CGRect) {
super.draw(rect)
let center = CGPoint(x: bounds.width / 2, y: bounds.height / 2)
let minLength = bounds.width <= bounds.height ? bounds.width : bounds.height
let circlePath = UIBezierPath (arcCenter: center, radius: CGFloat(minLength / 2), startAngle: 0, endAngle: CGFloat(Float(360).degreesToRadians) , clockwise: true)
let shapeLayer = CAShapeLayer()
shapeLayer.path = circlePath.cgPath
shapeLayer.fillColor = circleColor.cgColor
layer.addSublayer(shapeLayer)
}
但是,当我尝试在故事板中添加相同的自定义组件并在Draw方法中添加断点时,它没有被调用。出于好奇心,我为INIT添加了一个断点吗?(编码器AdeCoder:nscoder(方法。同样,当我尝试覆盖下面的方法时,它可以正常工作。
required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
drawCircle()
}
fileprivate func drawCircle() {
let center = CGPoint(x: bounds.width / 2, y: bounds.height / 2)
let minLength = bounds.width <= bounds.height ? bounds.width : bounds.height
let circlePath = UIBezierPath (arcCenter: center, radius: CGFloat(minLength / 2), startAngle: 0, endAngle: CGFloat(Float(360).degreesToRadians) , clockwise: true)
let shapeLayer = CAShapeLayer()
shapeLayer.path = circlePath.cgPath
shapeLayer.fillColor = circleColor.cgColor
layer.addSublayer(shapeLayer)
}
方法的问题是我有一个自定义属性CircleColor
@IBInspectable
public var circleColor : UIColor = UIColor.gray
调用init方法时尚未设置,并且总是绘制一个灰色圆圈。
请帮助我知道未调用抽奖方法的原因。
预先感谢
我不确定您的根错误在哪里,但您不应仅覆盖draw(:)
只是为了添加一层。这将意味着每次组件重新读者每次都会再次添加一个新层。那不是你想要的。
更改颜色属性时,还应确保更新层颜色。为此,只需保存对图层的引用:
private let shapeLayer = CAShapeLayer()
@IBInspectable
public var circleColor : UIColor = UIColor.gray {
didSet {
shapeLayer.fillColor = circleColor.cgColor
}
}
public override init(frame: CGRect = .zero) {
super.init(frame: frame)
updateLayer()
layer.addSublayer(shapeLayer)
}
required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
updateLayer()
layer.addSublayer(shapeLayer)
}
fileprivate func updateLayer() {
let center = CGPoint(x: bounds.width / 2, y: bounds.height / 2)
let minLength = min(bounds.width, bounds.height)
let circlePath = UIBezierPath(arcCenter: center, radius: minLength / 2, startAngle: 0, endAngle: CGFloat(Float(360).degreesToRadians), clockwise: true)
shapeLayer.path = circlePath.cgPath
shapeLayer.fillColor = circleColor.cgColor
}
override func layoutSubviews() {
super.layoutSubviews()
// update layer position
updateLayer()
}
如果您真的想覆盖draw(rect:)
,则根本不需要创建一层或覆盖初始化器:
@IBInspectable
public var circleColor : UIColor = UIColor.gray {
didSet {
setNeedsDisplay()
}
}
public override func draw(_ rect: CGRect) {
// no need to call super.draw(rect)
let center = CGPoint(x: bounds.width / 2, y: bounds.height / 2)
let minLength = min(bounds.width, bounds.height)
let circlePath = UIBezierPath(arcCenter: center, radius: minLength / 2, startAngle: 0, endAngle: .pi * 2, clockwise: true)
// the following methods use current CGContext
circleColor.set()
circlePath.fill()
}