ios - 具有静态间距的 UIStackView 子类

标签 ios swift uikit subclass

我正在创建 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以及如何避免它吗?

最佳答案

我认为这里发生了什么。您想要实现两件事:

  1. 默认情况下,MyStackView 的间距应为 8.0
  2. 该间距值不应从外部更改

要实现第一件事,您需要重写初始值设定项并在其中设置默认值。

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
    }

}

第二件事,您需要重写 spacinggettersetter 以获取对来自外部的任何更改的控制。

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/

相关文章:

ios - 更改 NavigationItem 提示时出现奇怪的动画

ios - 如何从IOS浏览器播放SWF动画文件?

ios - WebService 不完整 Objective-C

ios - 使用 UISaveVideoAtPathToSavedPhotosAlbum 并保存到自定义相册

iphone - 难以使 UIKeyboard 在 UINavigationController 中消失

ios - 将 UIButtons 添加到 ViewDidLoad 上的数组

swift - 如何在编辑时自动调整 Swift 中居中 UITextfield 的宽度?

ios - 浮点值用双引号从 [String : AnyObject] in swift

swift - 角度渐变层

ios - 保留UITouch : allowed or not?