【发布时间】:2019-02-27 08:08:56
【问题描述】:
Link to the relevant sample project
说明
我正在尝试创建一个自定义 NSCollectionViewLayout 子类,它使用自动布局来确定其项目的大小。这种布局从上到下定位项目,其中所有项目共享相同的宽度,但每个项目的高度由其内容决定。将其视为 macOS 的 UITableView 布局。
假设
初始布局属性在布局的prepare()方法中计算,并通过layoutAttributesForElements(in:)传递给collection view。集合视图使用这些属性来确定需要显示哪些项目。这些项目由集合视图的委托提供,并调用每个项目的 apply(_:) 方法来设置其视图属性。
然后集合视图将调用项目的preferredLayoutAttributesFitting(_:) 方法来计算其内容的合适大小。返回的属性随后将被传递到集合视图布局的 shouldInvalidateLayout(forPreferredLayoutAttributes:withOriginalAttributes:) 方法中,在该方法中布局确定是否需要针对新属性进行调整,并将该布尔决策返回给集合视图。
如果布局决定它需要失效,那么集合视图将调用invalidationContext(forPreferredLayoutAttributes:withOriginalAttributes:) 从布局中获取具体信息,以了解它应该如何自我更新。当集合视图随后调用invalidationContext(forPreferredLayoutAttributes:withOriginalAttributes:) 时,布局可以应用这些更改。
然后重复此过程,直到 shouldInvalidateLayout(forPreferredLayoutAttributes:withOriginalAttributes:) 为每个布局项返回 false — 提示集合视图在屏幕上显示这些项。
前提
NSCollectionViewLayout 的ListLayout 子类能够为每个NSCollectionViewItem 创建一组初始布局属性,“估计”初始高度为10 点。我们希望使用 Auto Layout 来确定每个项目的实际高度,所以这个初始值应该无关紧要。
然后布局能够通过layoutAttributesForElements(in:) 提供正确的初始属性集。
NSCollectionViewItem 的 TextFieldItem 子类包含一个 NSTextField 实例,该实例设置为其 view 和 textField 属性。此视图将其translatesAutoresizingMaskIntoConstraints 属性设置为false,并具有所需的垂直内容压缩阻力优先级。该项目的apply(_:) 方法被覆盖,以将文本字段的preferredMaxLayoutWidth 设置为给定属性提供的宽度。项目的 preferredLayoutAttributesFitting(_:) 方法被覆盖以将首选属性的高度设置为等于文本字段的 intrinsicContentSize 属性。
集合视图提供了TextFieldItem 的实例,其中填充了多行文本。
预计每个TextFieldItem 将在其apply(_:) 方法之后调用其preferredLayoutAttributesFitting(_:) 方法,然后调用布局的shouldInvalidateLayout(forPreferredLayoutAttributes:withOriginalAttributes:) 和invalidationContext(forPreferredLayoutAttributes:withOriginalAttributes:) 方法。
但是,在运行 Playground 时,不会调用 preferredLayoutAttributesFitting(_:)、shouldInvalidateLayout(forPreferredLayoutAttributes:withOriginalAttributes:) 和 invalidationContext(forPreferredLayoutAttributes:withOriginalAttributes:)。因此,每个项目的高度都保持在最初的“估计”高度。
问题
NSCollectionViewLayout 和自动布局一定是我遗漏了一些东西,但我在文档中没有找到任何表明这一点的内容。
我尝试在集合视图生命周期的各个不同点手动调用这些方法,但没有任何方法能够正确触发布局以调整其计算属性。
是否需要在集合视图、其布局或项目上设置一个属性来指示应该调用preferredLayoutAttributesFitting(_:)?自动布局是否仅支持 NSCollectionViewFlowLayout 和 NSCollectionViewGridLayout 的子类?还是我误解了NSCollectionViewLayout 实例的生命周期?
【问题讨论】:
-
如果您在反馈助手中提交报告,请在此处发布 FB #,我会尝试放大信号。
标签: macos appkit nscollectionview nscollectionviewitem nscollectionviewlayout