【问题标题】:Preview CAShapeLayer using IBDesignable and IBInspectable使用 IBDesignable 和 IBInspectable 预览 CAShapeLayer
【发布时间】:2017-08-02 21:29:11
【问题描述】:

我尝试创建一个包含形状图层的视图,可以在 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")
    }
}

【问题讨论】:

    标签: swift xcode uikit core-animation ibdesignable


    【解决方案1】:

    您正在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")
        }
    }
    

    【讨论】:

    • 谢谢你的帮助,昨天想不通了(已经很晚了..)!
    猜你喜欢
    • 1970-01-01
    • 2014-08-19
    • 1970-01-01
    • 2019-04-03
    • 1970-01-01
    • 2020-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多