IBInspectable 变量值在界面生成器和模拟器中没有改变
IBInspectable variable value is not changing in interface builder and simulator
我正在创建自定义平行四边形视图,该视图使用默认偏移值渲染良好。但是当我从 ib 更改偏移值时它不起作用
@IBDesignable class CustomParallelogramView: UIView {
@IBInspectable var offset: Float = 10.0
var path = UIBezierPath()
lazy var shapeLayer: CAShapeLayer = {
let layer = CAShapeLayer()
layer.path = path.cgPath
return layer
}()
override init(frame: CGRect) {
super.init(frame:frame)
drawParallelogram()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder:aDecoder)
drawParallelogram()
}
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
drawParallelogram()
}
override func layoutSubviews() {
super.layoutSubviews()
updateFrame()
}
func drawParallelogram() {
print(offset)
path.move(to: CGPoint(x: bounds.minX + CGFloat(offset), y: bounds.minY))
path.addLine(to: CGPoint(x: bounds.maxX, y: bounds.minY))
path.addLine(to: CGPoint(x: bounds.maxX - CGFloat(offset), y: bounds.maxY))
path.addLine(to: CGPoint(x: bounds.minX, y: bounds.maxY))
path.close()
self.layer.mask = shapeLayer
}
func updateFrame() {
shapeLayer.frame = bounds
}
}
我更改了 IB 的偏移值,但它不会更改 IB 和模拟器
尝试:
@IBInspectable var offset: Float = 10.0 {
didSet {
drawParallelogram()
}
}
几个想法:
正如丹尼尔所说,你真的想在你的 offset
观察者中调用 drawParallelgram
。
此外,在 layoutSubviews
中,您正在更新形状图层的 frame
。您想要重置其 path
并再次更新您的面具。
您只是在 UIBezierPath
中添加了越来越多的笔划。你可能只是想让它成为一个局部变量,避免在现有路径上添加越来越多的笔画。
prepareForInterfaceBuilder
暗示了对该方法的用途的一些误解。这不是为了在从 IB 启动时进行初始化。这是为了做一些特殊的配置,超出 init
方法已经完成的,IB 要求的。
例如如果你有一个复杂的图表视图,稍后你将以编程方式提供真实的图表数据,但你想在 IB 中看到一些东西,尽管如此,你可能 prepareForInterfaceBuilder
填充一些虚拟数据,例如。但是你不应该重复你已经在 init
方法中完成的配置。
这里不相关(因为我会建议摆脱这些 init
方法),但是对于它的价值,如果我需要在 [=19] 期间进行配置=],我一般写两个init
方法:
override init(frame: CGRect = .zero) {
super.init(frame: frame)
<#call configure routine here#>
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
<#call configure routine here#>
}
请注意,在 init(frame:)
中,我还提供了默认值 .zero
。这确保我涵盖了所有三种情况:
CustomView()
CustomView(frame:)
;或者
- 如果故事板调用
CustomView(decoder:)
。
简而言之,我以两个的价格获得三个init
方法。哈哈
综上所述,您可以大大简化它:
@IBDesignable public class CustomParallelogramView: UIView {
@IBInspectable public var offset: CGFloat = 10 { didSet { updateMask() } }
override public func layoutSubviews() {
super.layoutSubviews()
updateMask()
}
private func updateMask() {
let path = UIBezierPath()
path.move(to: CGPoint(x: bounds.minX + offset, y: bounds.minY))
path.addLine(to: CGPoint(x: bounds.maxX, y: bounds.minY))
path.addLine(to: CGPoint(x: bounds.maxX - offset, y: bounds.maxY))
path.addLine(to: CGPoint(x: bounds.minX, y: bounds.maxY))
path.close()
let shapeLayer = CAShapeLayer()
shapeLayer.path = path.cgPath
layer.mask = shapeLayer
}
}
我正在创建自定义平行四边形视图,该视图使用默认偏移值渲染良好。但是当我从 ib 更改偏移值时它不起作用
@IBDesignable class CustomParallelogramView: UIView {
@IBInspectable var offset: Float = 10.0
var path = UIBezierPath()
lazy var shapeLayer: CAShapeLayer = {
let layer = CAShapeLayer()
layer.path = path.cgPath
return layer
}()
override init(frame: CGRect) {
super.init(frame:frame)
drawParallelogram()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder:aDecoder)
drawParallelogram()
}
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
drawParallelogram()
}
override func layoutSubviews() {
super.layoutSubviews()
updateFrame()
}
func drawParallelogram() {
print(offset)
path.move(to: CGPoint(x: bounds.minX + CGFloat(offset), y: bounds.minY))
path.addLine(to: CGPoint(x: bounds.maxX, y: bounds.minY))
path.addLine(to: CGPoint(x: bounds.maxX - CGFloat(offset), y: bounds.maxY))
path.addLine(to: CGPoint(x: bounds.minX, y: bounds.maxY))
path.close()
self.layer.mask = shapeLayer
}
func updateFrame() {
shapeLayer.frame = bounds
}
}
我更改了 IB 的偏移值,但它不会更改 IB 和模拟器
尝试:
@IBInspectable var offset: Float = 10.0 {
didSet {
drawParallelogram()
}
}
几个想法:
正如丹尼尔所说,你真的想在你的
offset
观察者中调用drawParallelgram
。此外,在
layoutSubviews
中,您正在更新形状图层的frame
。您想要重置其path
并再次更新您的面具。您只是在
UIBezierPath
中添加了越来越多的笔划。你可能只是想让它成为一个局部变量,避免在现有路径上添加越来越多的笔画。prepareForInterfaceBuilder
暗示了对该方法的用途的一些误解。这不是为了在从 IB 启动时进行初始化。这是为了做一些特殊的配置,超出init
方法已经完成的,IB 要求的。例如如果你有一个复杂的图表视图,稍后你将以编程方式提供真实的图表数据,但你想在 IB 中看到一些东西,尽管如此,你可能
prepareForInterfaceBuilder
填充一些虚拟数据,例如。但是你不应该重复你已经在init
方法中完成的配置。这里不相关(因为我会建议摆脱这些
init
方法),但是对于它的价值,如果我需要在 [=19] 期间进行配置=],我一般写两个init
方法:override init(frame: CGRect = .zero) { super.init(frame: frame) <#call configure routine here#> } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) <#call configure routine here#> }
请注意,在
init(frame:)
中,我还提供了默认值.zero
。这确保我涵盖了所有三种情况:CustomView()
CustomView(frame:)
;或者- 如果故事板调用
CustomView(decoder:)
。
简而言之,我以两个的价格获得三个
init
方法。哈哈
综上所述,您可以大大简化它:
@IBDesignable public class CustomParallelogramView: UIView {
@IBInspectable public var offset: CGFloat = 10 { didSet { updateMask() } }
override public func layoutSubviews() {
super.layoutSubviews()
updateMask()
}
private func updateMask() {
let path = UIBezierPath()
path.move(to: CGPoint(x: bounds.minX + offset, y: bounds.minY))
path.addLine(to: CGPoint(x: bounds.maxX, y: bounds.minY))
path.addLine(to: CGPoint(x: bounds.maxX - offset, y: bounds.maxY))
path.addLine(to: CGPoint(x: bounds.minX, y: bounds.maxY))
path.close()
let shapeLayer = CAShapeLayer()
shapeLayer.path = path.cgPath
layer.mask = shapeLayer
}
}