具有静态间距的 UIStackView 子类
UIStackView subclass with static spacing
我正在创建 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
中 return 实际上并不重要,反正它从来没有被任何东西调用过。
任何人都可以解释这种行为]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
属性 是计算出来的,不是容器。我们可能不关心 original getter
是如何工作的,因为我们知道我们的间距总是相同的。我们知道它的价值,并且总是可以 return 它被覆盖 getter。
但我们也不知道原来的 setter
是如何工作的,它在 UIStackView
中做了什么改变。从那以后,我们不能简单地覆盖 getter
。我们必须显式调用 super.spacing = defaultValue
一次,以触发原始 setter
并设置所需的值。
我正在创建 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
中 return 实际上并不重要,反正它从来没有被任何东西调用过。
任何人都可以解释这种行为]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
属性 是计算出来的,不是容器。我们可能不关心 original getter
是如何工作的,因为我们知道我们的间距总是相同的。我们知道它的价值,并且总是可以 return 它被覆盖 getter。
但我们也不知道原来的 setter
是如何工作的,它在 UIStackView
中做了什么改变。从那以后,我们不能简单地覆盖 getter
。我们必须显式调用 super.spacing = defaultValue
一次,以触发原始 setter
并设置所需的值。