首页 > 解决方案 > 如何为自定义 UIView 提供设计时布局支持?

问题描述

只是在玩,看看能不能做点什么。我知道我可以通过添加某些属性来@IBInspectable为它们提供设计时支持,而且我还知道通过用@IBDesignable. 这一切都有效。我无法工作的是自定义布局支持。

考虑这个说明性的 UIView 子类......

@IBDesignable
public class SimpleStackView : UIView {

    public var spacing:CGFloat = 10 {
        didSet{
            setNeedsLayout()
        }
    }

    @IBInspectable
    public var insets = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10) {
        didSet{
            setNeedsLayout()
        }
    }

    public override func layoutSubviews() {

        var offset:CGFloat = insets.top

        let visibleSubviews = subviews.filter({ $0.isVisible })
        for view in visibleSubviews{

            let desiredSize = view.intrinsicContentSize

            view.frame = CGRect(
                x      : insets.left,
                y      : offset,
                width  : bounds.width - insets.left - insets.right,
                height : desiredSize.height)

            offset += desiredSize.height + spacing
        }
    }
}

注意:这不是全功能的——它不计算自己的内在高度作为例子——但它显示了基础知识

将以上内容添加SimpleStackView到 ViewController 的主视图中,将所有四个边缘固定到其容器,间距为 20,以及添加三个固有高度分别为 40、120 和 80 的子视图,您会得到预期的结果...

SimpleStackView 预览

同样,在运行时,这按预期工作。我想知道的是如何在设计时完成这项工作(如果有的话),因为这就是它目前的样子......

设计时的外观

注意:屏幕上的位置与视图本身的序号是无序的(即蓝色在运行时位于中间,但在设计时位于底部,因为设计时不正确(或根本没有!)订购/布置它们。

我知道普通的 StackView 支持这一点,但我想知道是不是因为以下原因:

  1. 由 Apple 设计,Xcode/IB 对此做出了特定的让步,或者...
  2. 因为它在一个单独的库中(我相信是动态的),因此是单独编译的,这允许它以不同的方式运行。

以上都是猜测,但我更倾向于认为它是#1。

那么可以实现设计时布局支持吗?如果是这样,怎么做?

标签: swiftxcodeinterface-builderibdesignableibinspectable

解决方案


推荐阅读