使用自定义流布局通过Dynamic Type 功能完美管理集合视图中标题的高度。
标题元素被视为集合视图的补充元素,referenceSizeForHeaderInSection“方法”仅用于初始化:它不使用Dynamic Type 功能调用。 ?
下面的解决方案基于自定义布局的layoutAttributesForElements 方法,由于UIFontMetrics scaledValue 将能够适应标题高度。
当用户更改字体大小时,由traitCollectionDidChange 中调用的invalidateLayout 方法触发的所有内容。 ?
步骤 1 ⟹ 创建一个简单的自定义标头类,例如:
class MyHeaderClass: UICollectionReusableView {
override init(frame: CGRect) { super.init(frame: frame) }
required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) }
}
第 2 步 ⟹ 创建一个新的空 .xib,添加一个可重用的视图,并将其命名为与其引用的类完全相同的名称:不要忘记在 @987654335 中更改其类名@。
第三步 ⟹在控制器中注册.xib文件:
collectionView.register(UINib(nibName: collectionViewHeaderFooterReuseIdentifier bundle: nil),
forSupplementaryViewOfKind: UICollectionElementKindSectionHeader,
withReuseIdentifier:collectionViewHeaderFooterReuseIdentifier)
第 4 步 ⟹ 在您的数据源中支持这个新单元格(标题是集合视图的补充元素):
func collectionView(_ collectionView: UICollectionView,
viewForSupplementaryElementOfKind kind: String,
at indexPath: IndexPath) -> UICollectionReusableView {
if (kind == UICollectionView.elementKindSectionHeader) {
let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind,
withReuseIdentifier: collectionViewHeaderReuseIdentifier,
for: indexPath) as! MyHeader
headerView.myLabel.text = "Your Header Title"
return headerView
} else {
return UICollectionReusableView(frame: CGRect.null) }
}
...并在您的委托中(这会初始化标题大小并使其出现):
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
referenceSizeForHeaderInSection section: Int) -> CGSize {
return CGSize(width: collectionView.frame.width, height: headerHeight)
}
.. 添加全局var headerHeight: CGFloat = 90.0 进行初始化后。
第 5 步 ⟹ 创建自定义流布局以使标题高度适应新的字体大小:
class FlowLayout: UICollectionViewFlowLayout {
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
let layoutAttributes = super.layoutAttributesForElements(in: rect)
layoutAttributes?.forEach({ (attribute) in
if (attribute.representedElementKind == UICollectionView.elementKindSectionHeader) {
headerHeight = UIFontMetrics.default.scaledValue(for: 22.0)
attribute.frame.size.height = headerHeight
}
})
return layoutAttributes
}
}
别忘了更新Interface Builder 中的情节提要:
STEP 6 ⟹ 当用户改变字体大小时,通知控制器触发布局更新:
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
if (previousTraitCollection?.preferredContentSizeCategory != traitCollection.preferredContentSizeCategory) {
collectionView?.collectionViewLayout.invalidateLayout()
}
}
根据这个原理,根据标题字体大小自动设置正确的标题高度 ⟹我建议使用Xcode 11 new feature快速测试Dynamic Type。 ?