我试图创建一个视图,其中包括一个可以在Xcode中预览的形状层。我不知道怎么能让它完全工作,尽管它的大部分工作。具体来说,我无法确定如何设置形状层的笔划属性,因为需要在添加层之前设置它,否则不会渲染笔划。但如果我之前设置了它,那么可检查的属性就不再工作了。我走了这么远:

import Foundation
import UIKit

@IBDesignable
class CustomView: UIView
{

    @IBInspectable var layerBackgroundColor: UIColor? {
        didSet {
            if let actualColor = layerBackgroundColor {
                layer.backgroundColor = actualColor.cgColor
            } else {
                layerBackgroundColor = nil
            }
        }
    }

    @IBInspectable var strokeColor: UIColor? = UIColor.red {
        didSet {
            if let actualColor = strokeColor {
                self.shapeLayer.strokeColor = actualColor.cgColor
            } else {
                shapeLayer.strokeColor = nil
            }
        }
    }

    private var shapeLayer: CAShapeLayer

    override func prepareForInterfaceBuilder()
    {
        let width = self.bounds.width
        let height = self.bounds.height

        shapeLayer = CAShapeLayer()
        shapeLayer.frame = CGRect(x: 0, y: 0, width: width, height: height)
        let path = CGMutablePath()
        let middle = width/2
        path.move(to:CGPoint(x:middle, y:20))

        path.addLine(to:CGPoint(x:middle, y:100))

        layerBackgroundColor = UIColor.gray
        // If this is not set no stroke will be rendered!
        strokeColor = UIColor.red
        shapeLayer.path = path
        shapeLayer.fillColor = nil
        shapeLayer.lineJoin = kCALineJoinRound
        shapeLayer.lineCap = kCALineCapRound
        shapeLayer.lineWidth = 5
        layer.addSublayer(shapeLayer)

    }


    override init(frame: CGRect)
    {
        shapeLayer = CAShapeLayer()
        super.init(frame:frame)
    }

    required init?(coder aDecoder: NSCoder)
    {
        fatalError("init(coder:) has not been implemented")
    }
}

最佳答案

您正在prepareForInterfaceBuilder中创建新的shapeLayer,因此需要在该方法中设置shapeLayer的颜色属性。可检查变量是在初始化后但在prepareForInterfaceBuilder之前分配的,因此在prepareForInterfaceBuilder中创建新的CAShapeLayer会破坏以前的分配。我假设在实践中,您将在另一个方法中为您的类执行自定义绘图(因为这个方法从未在IB之外调用)。
不管怎样,下面的代码应该可以解决您在IB上的问题,我做了四个修改,都发表了评论。。。。

import Foundation
import UIKit

@IBDesignable
class CustomView: UIView
{
    @IBInspectable var layerBackgroundColor: UIColor? {
        didSet {
            if let actualColor = layerBackgroundColor {
                layer.backgroundColor = actualColor.cgColor
            } else {
                layerBackgroundColor = nil
            }
        }
    }

    @IBInspectable var strokeColor: UIColor? {//1 -  Maybe you want to comment out assignment to UIColor.red:   = UIColor.red {
        didSet {
            if let actualColor = strokeColor {
                self.shapeLayer.strokeColor = actualColor.cgColor
            } else {
                shapeLayer.strokeColor = nil
            }
        }
    }

    private var shapeLayer: CAShapeLayer

    override func prepareForInterfaceBuilder()
    {
        let width = self.bounds.width
        let height = self.bounds.height

        shapeLayer = CAShapeLayer()
        shapeLayer.frame = CGRect(x: 0, y: 0, width: width, height: height)
        let path = CGMutablePath()
        let middle = width/2
        path.move(to:CGPoint(x:middle, y:20))

        path.addLine(to:CGPoint(x:middle, y:100))

        //2 - you probably also want to set the shapeLayer's background color to the class variable, not hardcode the class variable
        //layerBackgroundColor = UIColor.gray
        shapeLayer.backgroundColor = layerBackgroundColor?.cgColor


        // If this is not set no stroke will be rendered!
        //3 Comment the hardcoding line out
        //strokeColor = UIColor.red
        //4 - assign the shapeLayer's stroke color
        shapeLayer.strokeColor = strokeColor?.cgColor

        shapeLayer.path = path
        shapeLayer.fillColor = nil
        shapeLayer.lineJoin = kCALineJoinRound
        shapeLayer.lineCap = kCALineCapRound
        shapeLayer.lineWidth = 5
        layer.addSublayer(shapeLayer)

    }


    override init(frame: CGRect)
    {
        shapeLayer = CAShapeLayer()
        super.init(frame:frame)
    }

    required init?(coder aDecoder: NSCoder)
    {
        fatalError("init(coder:) has not been implemented")
    }
}

关于swift - 使用IBDesignable和IBInspectable预览CAShapeLayer,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45471312/

10-13 03:55