gpt4 book ai didi

ios - 仅在首次初始化自定义 UIView 时如何在 LayoutSubviews 中执行代码

转载 作者:可可西里 更新时间:2023-11-01 01:44:36 24 4
gpt4 key购买 nike

我们有一个在 Interface Builder 中使用约束的自定义 UIView,我们修改了此 View 以具有我们需要绘制的自定义形状。

形状大小取决于在 Interface Builder 中应用于此自定义 View 的约束,因此为了在自定义 UIView 中获得正确大小的形状,我们需要在 LayoutSubviews 中调用它。

问题是在屏幕方向期间调用 LayoutSubviews 时,另一个形状被添加到屏幕,因为它是在自定义 UIView 的设置函数中调用的。

可以通过添加一个 bool 值来解决此行为,该 bool 值确定这是否是第一次调用 LayoutSubviews,只有在调用时,才将形状层添加到 View 。

我在这里和网上做了一些研究,找到了一篇关于如何使用不同方法实现所描述行为的文章。

https://thomasclowes.com/ios-when-to-layout-your-views/

作者提到了一个自定义类 BaseView 和一个可以实现的协议(protocol)来解决这个问题。

解决方案写在“UIView and layoutSubviews”下。

我正在努力理解该解决方案,想知道是否有人可以澄清并展示一个代码示例,说明如何实现本文中提到的解决方案。

提前致谢。

class CustomView: UIView {

private var firstTimeInit = true

override func layoutSubviews() {
super.layoutSubviews()

setup()
}

private func setup() {

// Check if the the method was already executed
if firstTimeInit == false { return }

let label = UILabel(frame: CGRect(x: 0, y: 0, width: 0, height: 21))
label.font = UIFont.systemFont(ofSize: 13, weight: .bold)
label.text = "Daily"
label.textAlignment = .center
label.sizeToFit()
addSubview(label)
label.center.x = bounds.midX

let shapePath = UIBezierPath()
shapePath.move(to: CGPoint(x: 0, y: 0))
shapePath.addLine(to: CGPoint(x: frame.width, y: 0))

let shapeLayer = CAShapeLayer()
shapeLayer.path = shapePath.cgPath
shapeLayer.strokeColor = UIColor(hex: 0xD5E5EF).cgColor
shapeLayer.lineWidth = 3
shapeLayer.lineCap = .round
shapeLayer.position.y = frame.height / 2
shapeLayer.lineDashPattern = [frame.width / 2.5, frame.width / 5, frame.width / 2.5] as [NSNumber]
layer.addSublayer(shapeLayer)

firstTimeInit = false
}
}

最佳答案

为什么不创建一次 UILabelCAShapeLayer,将其添加到构造函数中的 subview ,然后只使用 layoutSubviews 重新计算它们框架还是图案?

像这样:

class CustomView: UIView {

private let label = UILabel(frame: CGRect(x: 0, y: 0, width: 0, height: 21))
private let shapeLayer = CAShapeLayer()

override init(frame: CGRect) {
super.init(frame: frame)

label.font = UIFont.systemFont(ofSize: 13, weight: .bold)
label.text = "Daily"
label.textAlignment = .center
addSubview(label)

shapeLayer.strokeColor = UIColor(hex: 0xD5E5EF).cgColor
shapeLayer.lineWidth = 3
shapeLayer.lineCap = .round
layer.addSublayer(shapeLayer)
}

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

override func layoutSubviews() {
super.layoutSubviews()

label.sizeToFit()
label.center.x = bounds.midX

let shapePath = UIBezierPath()
shapePath.move(to: CGPoint(x: 0, y: 0))
shapePath.addLine(to: CGPoint(x: frame.width, y: 0))

shapeLayer.path = shapePath.cgPath
shapeLayer.position.y = frame.height / 2
shapeLayer.lineDashPattern = [frame.width / 2.5, frame.width / 5, frame.width / 2.5] as [NSNumber]
}
}

这样您的自定义形状将适应 frame 变化,而不会 self 复制。

显然,如果使用它,您可能需要实际实现required init?(coder aDecoder: NSCoder)

关于ios - 仅在首次初始化自定义 UIView 时如何在 LayoutSubviews 中执行代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57687307/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com