类型"CAShapeLayer"的值没有成员"leaderAnchor" [英] Value of type 'CAShapeLayer' has no member 'leadingAnchor'

查看:79
本文介绍了类型"CAShapeLayer"的值没有成员"leaderAnchor"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个圆形,可以使用CAShapeLayer绘制.现在,我想将我的按钮约束到该层的前导锚点,但是然后出现此错误类型为'CAShapeLayer'的值没有成员'leadingAnchor'".我怎样才能解决这个问题. 代码:

I have a circular shape which I use CAShapeLayer to draw. Now I want to constraint my button to the leading anchor of the layer but then I get this error "Value of type 'CAShapeLayer' has no member 'leadingAnchor'". How can I fix this. Code:

btnSMSIcon.leadingAnchor.constraint(equalTo: shapeLayer.leadingAnchor, constant: 60).isActive = true

推荐答案

AutoLayout处理视图,而不是图层.如果要在自动版式中包括一个图层,请将该图层附加到视图.

AutoLayout deals with views, not layers. If you want to include a layer in your AutoLayout, attach the layer to a view.

(您可以创建一个内容层是形状层的自定义UIView,然后将您的自定义UIView放在情节提要中.调整视图的大小时,衬背层的大小也将被调整.)

(You can create a custom UIView who's content layer is a shape layer, and then place your custom UIView in your storyboard. When you resize the view, the backing layer gets resized too.)

示例代码:

class ShapeView: UIView {

    override class var layerClass: AnyClass {
        return CAShapeLayer.self
    }

}

请注意,如果您使用UIView的自定义子类,其中视图的layerClassCAShapeLayer,则如果调整视图的大小,形状层将重新调整大小,但是不会重新生成路径.如果边界大小更改,则需要告诉视图重新生成其路径.一种方法是在视图控制器中实现viewDidLayoutSubviews()并让viewDidLayoutSubviews()告诉自定义视图重建其路径.

Note that if if you use a custom subclass of UIView where the view's layerClass is a CAShapeLayer the shape layer will resize if the view resizes, but the path won't get regenerated. You need to tell the view to regenerate it's path if its bounds size changes. One way to do that is to implement viewDidLayoutSubviews() in the view controller and have viewDidLayoutSubviews() tell the custom view to rebuild it's path.

另一种处理方法是在视图的bounds属性中添加didSet并在其中重建形状.

Another way to handle it is to add a didSet to the view's bounds property and rebuild the shape there.

作为一个实验,我如上所述实现了ShapeView.我决定给它一个名为createPathClosure的闭包,该闭包创建它安装在shape层中的路径,并使它对视图范围内的更改做出响应.当范围更改时,它会调用闭包来重建路径.

As an experiment I implemented a ShapeView as described above. I decided to give it a closure, called createPathClosure that creates the path it installs in the shape layer, and make it respond to changes in the view's bounds. When the bounds change it invokes the closure to rebuild the path.

该视图会在初始化期间安装默认的闭包,但是如果您要绘制其他路径,则可以在设置视图控制器时替换该闭包:

The view installs a default closure during initialization, but you can replace the closure when you set up a view controller if you want a different path to be drawn:

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)
        }
    }
}

这篇关于类型"CAShapeLayer"的值没有成员"leaderAnchor"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆