我正在创建 UIStackView 的子类,并且我希望间距是静态的且不可覆盖。我认为这可以通过覆盖 spacing
属性来简单地完成:
class MyStackView: UIStackView {
override var spacing: CGFloat {
get { return 8.0 }
set {}
}
}
但是,这不起作用。 getter 永远不会被调用,并且不会显示间距。我找到的唯一解决方案是以下代码:
class MyStackView: UIStackView {
override init(frame: CGRect) {
super.init(frame: frame)
super.spacing = 8.0
}
override var spacing: CGFloat {
get { return 8.0 }
set {}
}
}
实际上,我在 get
中返回什么并不重要,无论如何它都不会被任何东西调用。
任何人都可以解释这种行为]r以及如何避免它吗?
最佳答案
我认为这里发生了什么。您想要实现两件事:
- 默认情况下,
MyStackView
的间距应为8.0
- 该间距值不应从外部更改
要实现第一件事,您需要重写初始值设定项并在其中设置默认值。
class MyStackView: UIStackView {
private let defaultSpacing: CGFloat = 8.0
override init(frame: CGRect) {
super.init(frame: frame)
super.spacing = defaultSpacing
}
required init(coder: NSCoder) {
super.init(coder: coder)
super.spacing = defaultSpacing
}
}
第二件事,您需要重写 spacing
的 getter
和 setter
以获取对来自外部的任何更改的控制。
class MyStackView: UIStackView {
...
override var spacing: CGFloat {
get { return defaultSpacing }
set { print("MyStackView spacing it always \(defaultSpacing)") }
}
}
为什么不能简单地覆盖变量并获得相同的结果?
UIStackView.spacing
属性是计算出来的,它不是一个容器。我们可能不关心原始的 getter 是如何工作的,因为我们知道我们的间距总是相同的。我们知道它的值并且总是可以在重写的 getter 处返回它。
但我们也不知道原来的 setter
是如何工作的,以及它在 UIStackView
中做了什么改变。从那时起,我们就不能简单地重写getter
。我们必须显式调用一次 super.spacing = defaultValue
来触发原始 setter
并设置所需的值。
关于ios - 具有静态间距的 UIStackView 子类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52188270/