我有一个圆形的形状,我使用CAShapeLayer绘制。现在我想把我的按钮限制在层的前导锚点上,但是我得到了这个错误“类型为'CAShapeLayer‘的值没有成员'leadingAnchor'”。我怎么才能解决这个问题。代码:
btnSMSIcon.leadingAnchor.constraint(equalTo: shapeLayer.leadingAnchor, constant: 60).isActive = true
发布于 2018-10-14 19:38:27
AutoLayout处理视图,而不是层。如果要在AutoLayout中包含图层,请将该图层附加到视图。
(您可以创建一个自定义的UIView who的内容层是一个形状层,然后将您的自定义UIView放在情节提要中。当您调整视图大小时,背景层的大小也会随之调整。)
示例代码:
class ShapeView: UIView {
override class var layerClass: AnyClass {
return CAShapeLayer.self
}
}
编辑:
请注意,如果使用UIView的自定义子类,其中视图的layerClass
是CAShapeLayer
,则如果视图调整大小,形状层将调整大小,但不会重新生成路径。如果它的边界大小改变,你需要告诉视图重新生成它的路径。要做到这一点,一种方法是在视图控制器中实现viewDidLayoutSubviews()
,并让viewDidLayoutSubviews()
告诉自定义视图重新构建其路径。
处理它的另一种方法是在视图的bounds
属性中添加一个didSet
,并在那里重新构建形状。
编辑#2
作为实验,我实现了一个如上所述的ShapeView
。我决定给它一个闭包,称为createPathClosure
,它创建它安装在shape层中的路径,并使它响应视图边界的变化。当边界改变时,它调用闭包来重新构建路径。
视图在初始化期间安装默认闭包,但如果您希望绘制不同的路径,则可以在设置视图控制器时替换闭包:
class ShapeView: UIView {
//This closure will be called when the view needs to rebuild the path for it's shape layer.
public var createPathClosure: ((ShapeView) -> Void)?
public var lineWidth: CGFloat = 5 {
didSet {
createPathClosure?(self)
}
}
override var bounds: CGRect {
didSet {
createPathClosure?(self)
}
}
//This class variable tells the system what kind of CALayer to create for this view.
//This view's backing layer is a CAShapeLayer.
override class var layerClass: AnyClass {
return CAShapeLayer.self
}
var shape: UIBezierPath? {
didSet {
guard let layer = layer as? CAShapeLayer,
let shape = shape else { return }
layer.path = shape.cgPath
}
}
override init(frame: CGRect) {
super.init(frame: frame)
setupShapeLayer()
createPathClosure?(self)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupShapeLayer()
createPathClosure?(self)
}
func setupShapeLayer() {
//Set the stroke color, stroke width, and fill color for the shape layer.
guard let layer = layer as? CAShapeLayer else { return }
layer.strokeColor = UIColor.blue.cgColor
layer.lineWidth = lineWidth
layer.fillColor = UIColor.yellow.cgColor
//Define a placeholder createPathClosure (can be replaced)
createPathClosure = { shapeView in
let center = shapeView.superview?.convert(shapeView.center, to: shapeView) ?? CGPoint.zero
let radius = min(shapeView.bounds.size.width, shapeView.bounds.size.height)/2.0 - shapeView.lineWidth / 2.0
shapeView.shape = UIBezierPath(arcCenter: center,
radius: radius,
startAngle: 0,
endAngle: 2 * CGFloat.pi,
clockwise: true)
}
}
}
https://stackoverflow.com/questions/52802176
复制相似问题