简体   繁体   English

具有静态间距的 UIStackView 子类

[英]UIStackView subclass with static spacing

I am creating a subclass of UIStackView, and I want spacing to be static and non-overwritable.我正在创建 UIStackView 的子类,我希望间距是静态的且不可覆盖。 I thought this would be simply done by overriding the spacing property:我认为这可以通过覆盖spacing属性来简单地完成:

class MyStackView: UIStackView {
    override var spacing: CGFloat {
        get { return 8.0 }
        set {}
    }
}

This, however, does not work.然而,这行不通。 The getter is never called and no spacing is displayed.永远不会调用 getter 并且不显示任何间距。 The only solution I found for this is the following piece of code:我为此找到的唯一解决方案是以下代码:

class MyStackView: UIStackView {
    override init(frame: CGRect) {
        super.init(frame: frame)
        super.spacing = 8.0
    }

    override var spacing: CGFloat {
        get { return 8.0 }
        set {}
    }
}

It actually doesn't matter what I return in get , it's never called by anything anyway.实际上,我在get返回什么并不重要,无论如何都不会调用它。

Can anybody explain this behavious]r and how to avoid it?任何人都可以解释这种行为以及如何避免它?

In my opinion here what's happening.在我看来这里发生了什么。 You want to achieve two things:你想实现两件事:

  1. Spacing at MyStackView should be 8.0 by default默认情况下, MyStackView间距应为8.0
  2. That spacing value should not be changeable from outside该间距值不应从外部更改

To achieve the first thing you need to override the initializers and set your default value inside on them.要实现第一件事,您需要覆盖初始值设定项并在其中设置默认值。

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
    }

}

For the second thing, you need to override the getter and setter of spacing to get the control on any changing from the outside.对于第二件事,您需要覆盖spacinggettersetter ,以控制从外部进行的任何更改。

class MyStackView: UIStackView {

    ...

    override var spacing: CGFloat {
        get { return defaultSpacing }
        set { print("MyStackView spacing it always \(defaultSpacing)") }
    }

}

Why can't you simply override a variable and get the same result?为什么不能简单地覆盖一个变量并获得相同的结果?

UIStackView.spacing property is computed, it's not a container. UIStackView.spacing属性是计算出来的,它不是一个容器。 We might not care how does original getter works because we know that our spacing is always the same.我们可能不关心原始getter是如何工作的,因为我们知道我们的间距总是相同的。 We know its value and can always return it at overriden getter.我们知道它的价值,并且总是可以在覆盖的 getter 中返回它。

But we also don't know how does original setter works and what changes does it make in UIStackView .但我们也不知道原始setter是如何工作的,以及它在UIStackView做了什么改变。 Since that, we can't simply override getter .从那以后,我们不能简单地覆盖getter We have to explicitly call super.spacing = defaultValue once, to trigger original setter and set the desired value.我们必须显式调用super.spacing = defaultValue一次,以触发原始setter并设置所需的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM