如何使自动布局与XIB上的自定义UIView一起使用?

时间:2018-12-19 21:23:46

标签: ios uiview autolayout

我在XIB上有一个UIView,其中包含一个UIImageView和一个UILabel,两者之间的间隔很小。水平布局是简单链接的|--image--label--|,其中--是一些固定的空间。高度固定为40,此视图在其视图控制器中水平居中,并且具有>= 100宽度约束。

如果我更改标签文本,则组合视图的宽度将按照其标签更改后的宽度的预期宽度进行更新,并且它将很好地保持在视图控制器的中心。

因为我需要这个UIView,其中包含图像和标签,所以在其他地方,我创建了一个包含XIB和Swift文件的自定义类。我们称之为ItemView

问题是我的视图控制器XIB上的空UIView(已将类更改为ItemView)不再接受>= 40宽度约束。当然,这是因为视图控制器XIB不再看到变量宽度UILabel,而只能看到类UIView的普通ItemView。我收到“不平等约束歧义” IB错误。

结果是我的自定义视图的宽度保持40。如果我指定更大的> =标签宽度,它会起作用。然后,仅在达到此宽度时才截取文本。但是在第二种情况下,我的自定义视图不再水平居中,而是向左移动了一点。

我该如何解决?或者,如何告诉IB以与ItemView类似的方式对待我的自定义UILabel

在我的ItemView中,我已经尽力找到了:

override class var requiresConstraintBasedLayout: Bool
{
    return true
}

设置标签文本后致电setNeedsLayout()

致电myLabel.translatesAutoresizingMaskIntoConstraints = false

致电self.translatesAutoresizingMaskIntoConstraints = false

然后在两个self.setNeedsUpdateConstraints()中调用init()

2 个答案:

答案 0 :(得分:1)

在视图的大小检查器中配置此弹出窗口:

enter image description here

现在IB不必担心您的尺寸规格。您比IB更了解,这就是告诉IB这一事实的方法。


另一种方法:在视图的“大小”检查器中配置“ ”弹出窗口:

enter image description here

这告诉IB,视图将具有它不知道的固有内容大小。


其中任何一个都可以使用。如您在此屏幕快照中所见,我给自定义视图的宽度限制大于或等于40,但是IB并没有抱怨任何错误:

enter image description here

答案 1 :(得分:0)

我如何构造自定义UIView:XIB的文件所有者是ItemViewItemView的{​​{1}}已连接到XIB中的视图。然后我有:

@IBOutlet var: UIView!

(我似乎用XIB创建自定义init() { super.init(frame: .zero) self.initView() } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) self.initView() } private func initView() { Bundle.main.loadNibNamed("ItemView", owner: self, options: nil) self.view.frame = CGRect(x: 0.0, y: 0.0, width: self.width, height: self.height) self.addSubview(self.view!) } 时需要额外的UIView。很想听听是否不需要它。)

要使其正常工作,我需要在更新标签后调用UIView。并覆盖self.invalidateIntrinsicContentSize()

intrinsicContentSize

请注意,我是在override open var intrinsicContentSize: CGSize { return self.view.systemLayoutSizeFitting(self.bounds.size) } 而不是在self.view上打电话。

感谢@matt向我指出正确的方向。这是我第一次遇到这样的事情。

以下我们尝试过的所有操作都是不必要的:

self

设置标签文本后致电override class var requiresConstraintBasedLayout: Bool { return true }

致电setNeedsLayout()

致电myLabel.translatesAutoresizingMaskIntoConstraints = false

然后在两个self.translatesAutoresizingMaskIntoConstraints = false中调用self.setNeedsUpdateConstraints()