使用 IBDesignable 和 IBInspectable 预览 CAShapeLayer
Preview CAShapeLayer using IBDesignable and IBInspectable
我尝试创建一个包含形状图层的视图,可以在 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 会破坏您之前的分配。我假设在实践中你将在另一种方法中为你的 class 做自定义绘图(因为这个方法永远不会在 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")
}
}
我尝试创建一个包含形状图层的视图,可以在 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 会破坏您之前的分配。我假设在实践中你将在另一种方法中为你的 class 做自定义绘图(因为这个方法永远不会在 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")
}
}