UIStackView背景色和自定义间距

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UIStackView背景色和自定义间距相关的知识,希望对你有一定的参考价值。

参考技术A APP最低支持ios9.0,部分布局开始使用UIStackView。但是其有些许局限性,比如不能设置背景颜色、在iOS11之后才支持对间距的不同调整。鉴于此,对其进行了一些尝试。
一、对背景颜色的支持。
UIStackView是UIView 的子类,但是官方说在层级中是不对其渲染。然后抱着尝试 的心态,在UIStackView的子类中重写了 + (Class)layerClass ,然后按UI View 的方法设置背景颜色、圆角等,竟然生效了。奈斯!

二、对自定义间距的尝试。
在iOS11中新增了 - (void)setCustomSpacing:(CGFloat)spacing afterView:(UIView *)arrangedSubview ,可以对该subview之后的间距做出调整,着实有用。遂也重写该方法。 customSpacingView 是一个保存arrangedSubview的集合,简单的保证唯一性,待之后布局调整时使用。本文章只是一些尝试,暂为保存要设定的spacing。然后输出所有的 constraints ,发现一个可疑对象constraint的 identifier 值为 UISV-spacing ,修改其值(统一值为5,该处固定调到15),又生效了。太奈斯拉。

本篇文章只是对UIStackView一些想法,具体用法或其它属性可以参考官方文档。demo中有很多细节并没有完全考虑,使用中或许需要优化。哪位大佬有好的想法,或者有好的指导问题,欢迎留言。
谢谢。

具有静态间距的UIStackView子类

我正在创建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返回,它从来没有被任何东西调用。

任何人都可以解释这种行为以及如何避免它吗?

答案

在我看来,这是怎么回事。你想要实现两件事:

  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
    }

}

第二件事,你需要覆盖gettersetterspacing来控制外部的任何变化。

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并设置所需的值。

以上是关于UIStackView背景色和自定义间距的主要内容,如果未能解决你的问题,请参考以下文章

基于模板创建自定义视图

UIStackView 调整我的视图大小

UIStackView 中的图像未四舍五入

UniGUI的TUniLoginForm窗口自定义背景色和背景图片

具有静态间距的UIStackView子类

UIStackView 的约束在设置间距时中断