azh*_*har 2 uiview swift ibinspectable
我正在创建自定义平行四边形视图,并且视图使用默认偏移值渲染得很好。但是当我改变 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
}
}
Run Code Online (Sandbox Code Playgroud)
我更改了 IB 的偏移值,但它不会更改 IB 和模拟器
有几点想法:
\n\n正如丹尼尔所说,你真的想召集drawParallelgram你的offset观察员。
另外,在 中layoutSubviews,您\xe2\x80\x99 正在更新frame形状图层的 。您想重置它path并再次更新您的面具。
您\xe2\x80\x99 只是向您的UIBezierPath. 您可能只想将其设为局部变量,并避免向现有路径添加越来越多的笔划。
这prepareForInterfaceBuilder表明人们对这种方法的目的存在一些误解。这是\xe2\x80\x99t,用于从 IB 启动时进行初始化。这是为了进行一些特殊的配置,超出了initIB 所要求的方法已经完成的配置。
例如,如果您有一个复杂的图表视图,您\xe2\x80\x99 将在稍后以编程方式提供真实的图表数据,但您想在 IB 中看到某些内容,尽管如此,您可能已经填充了prepareForInterfaceBuilder一些虚拟数据。但是您不应该\xe2\x80\x99 重复已在方法中完成的配置init。
它\xe2\x80\x99s在这里不相关(因为我\xe2\x80\x99m会建议摆脱这些init方法),但是对于它\xe2\x80\x99s的价值,如果我需要在期间进行配置init,我一般写两个init方法:
override init(frame: CGRect = .zero) {\n super.init(frame: frame)\n\n <#call configure routine here#>\n}\n\nrequired init?(coder aDecoder: NSCoder) {\n super.init(coder: aDecoder)\n\n <#call configure routine here#>\n}\nRun Code Online (Sandbox Code Playgroud)\n\n请注意,init(frame:)我还提供了默认值.zero。这确保了 I\xe2\x80\x99m 涵盖所有三种情况:
CustomView()CustomView(frame:); 或者CustomView(decoder:).简而言之,我用init两种方法的价格得到了三种方法。哈哈。
话虽如此,您可以大大简化这一点:
\n\n@IBDesignable public class CustomParallelogramView: UIView {\n\n @IBInspectable public var offset: CGFloat = 10 { didSet { updateMask() } }\n\n override public func layoutSubviews() {\n super.layoutSubviews()\n updateMask()\n }\n\n private func updateMask() {\n let path = UIBezierPath()\n path.move(to: CGPoint(x: bounds.minX + offset, y: bounds.minY))\n path.addLine(to: CGPoint(x: bounds.maxX, y: bounds.minY))\n path.addLine(to: CGPoint(x: bounds.maxX - offset, y: bounds.maxY))\n path.addLine(to: CGPoint(x: bounds.minX, y: bounds.maxY))\n path.close()\n\n let shapeLayer = CAShapeLayer()\n shapeLayer.path = path.cgPath\n layer.mask = shapeLayer\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n