我有一个自定义NSView的层次结构,该布局以自动布局约束不支持的样式进行布局。现在,我只是在监视调整大小的事件,并在我的所有 subview (及其 subview ...)上调用-setFrame,但是就源代码复杂性而言,扩展性不是很好。 (当我在层次结构的底部添加一个新的 subview 时,我必须在顶 View 中向上添加其布局逻辑,这似乎并不理想。)

据我所知,解决此问题的正确方法是重写NSView的-layout方法(然后在我想在树的某个级别强制布局时调用-setNeedsLayout)。

不幸的是,它的文档有点简洁,而且(尽管那里有“CocoaSlides”链接),Apple没有示例代码可以覆盖此方法。我尝试在Github上搜索,但事实证明,“布局”在Objective-C代码中是一个相当普遍的词,而我还没有找到我想要的那个。

例如,假设我有一个AAView(NSView),它的内部有一些BBView,可以显示一些文字换行的文本,并且它想以其自身宽度的100%显示它们(我想就像是NSStackView,尽管这是Cocoa的另一个完全未记录的功能)。

由于BBView的高度取决于其宽度(由于自动换行),因此它们不能具有-intrinsicContentSize(对吗?)。 AAView的-layout方法要放置BBView,即设置其frameSize和frameOrigin。为了知道BBView的大小,它需要询问BBView,但是BBView不能在其-layout方法中设置自己的大小(如果有 subview ,则仅用于其 subview )。因此,在这些类中对-layout的任何实现也都需要一些带外方法(例如BBView上的-requestedHeightForWidth:(CGFloat)width),在这一点上,我不确定这是否比我自己的即席-setFrame调用更好(例如, CocoaSlides实际执行的操作)。

有人可以指出一些示例代码,该示例代码为自定义NSView实现-layout吗?我只是没有看到它应该如何工作。我是不是完全错在树上?

最佳答案

我相信您可以在BBView上使用-intrinsicContentSize进行自动布局,假设我了解问题所在。

如果您的BBView始终希望始终为AAView的确切宽度(或近似于该宽度),则可以设置标准水平约束以强制执行此操作。那解决了宽度。

要执行高度调整,请在BBView上覆盖-setFrameSize:,如果宽度已从旧宽度更改,则调用-invalidateIntrinsicContentSize。

在BBView的-intrinsicContentSize中,查看当前宽度并根据字符串在其中的布局方式计算高度。返回{self.frame.width,CalculationHeight},您无家可归。 (如果大量调用-intrinsicContentSize且布局昂贵,则可以进行明显的优化。)

编辑:实际上,您应该返回(NSSize){NSViewNoInstrinsicMetric,计算高度},而不是当前宽度。对不起。

10-08 00:36