UICollectionView 使用辅助功能自动调整具有动态列数的单元格
UICollectionView autosize cell with dynamic number of columns using Accessibility
我正在尝试模仿当前快捷方式应用程序 UICollectionView 的行为,其中项目的默认显示采用 2 列布局,但根据字体大小,它会更改为单列,单元格占据collection 视图的全宽。
我正在将动态类型添加到我的单元格标签,如果用户转到 phone 辅助功能并增加字体大小,我的标签也会增加,但现在标签字体增加但单元格只会增加在高度上,我的 collection 视图最终变成了两列,单元格非常高。
我目前使用的是没有任何自定义的基本流布局。我没有可用的或好的代码可以分享,但我正在寻找有关实现此目标的最佳方法的建议。
我的目标是 iOS 14,并使用 swift 5。
编辑
感谢 Witek 的回答,我能够使用 UICollectionViewCompositionalLayout 非常轻松地完成此操作,而且我什至不必订阅更改,只需在我的布局中查询 traitCollection 就足够了。这是我的最终结果:
private func createCompositionalLayout() -> UICollectionViewLayout {
let layout = UICollectionViewCompositionalLayout { (sectionIndex: Int,
layoutEnvironment: NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection? in
let columns = self.traitCollection.preferredContentSizeCategory.isAccessibilityCategory ? 1 : 2
// Define Item Size
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(1.0))
// Create Item
let item = NSCollectionLayoutItem(layoutSize: itemSize)
// Define Group Size
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(150.0))
// Create Group
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitem: item, count: columns)
group.interItemSpacing = .fixed(10.0)
// Create Section
let section = NSCollectionLayoutSection(group: group)
// Configure Section
section.contentInsets = NSDirectionalEdgeInsets(top: 10.0, leading: 10.0, bottom: 10.0, trailing: 10.0)
section.interGroupSpacing = 10
return section
}
return layout
}
您可以观察 UIContentSizeCategory.didChangeNotification
并根据通知中传递的 newValueUserInfoKey
值更改列数(单元格大小)。
@objc private func sizeCategoryDidChange() {
collectionView.reloadData()
}
NotificationCenter.default.addObserver(
self, selector: #selector(sizeCategoryDidChange),
name: UIContentSizeCategory.didChangeNotification, object: nil
)
首选内容大小类别也可以很容易地从 UIApplication.shared
中检索到
let contentSizeCategory = UIApplication.shared.preferredContentSizeCategory
快捷方式应用程序似乎根据 isAccessibilityCategory
属性 进行布局,以确定当前内容类别是否属于可访问性类别之一
let cellWidth: CGFloat
let padding: CGFloat = 16
if contentSizeCategory.isAccessibilityCategory {
// single column, full width with padding
cellWidth = collectionView.bounds.width - (padding * 2)
} else {
// double column, half width with padding
cellWidth = (collectionView.bounds.width - (padding * 3)) / 2
}
文档:
我正在尝试模仿当前快捷方式应用程序 UICollectionView 的行为,其中项目的默认显示采用 2 列布局,但根据字体大小,它会更改为单列,单元格占据collection 视图的全宽。
我正在将动态类型添加到我的单元格标签,如果用户转到 phone 辅助功能并增加字体大小,我的标签也会增加,但现在标签字体增加但单元格只会增加在高度上,我的 collection 视图最终变成了两列,单元格非常高。
我目前使用的是没有任何自定义的基本流布局。我没有可用的或好的代码可以分享,但我正在寻找有关实现此目标的最佳方法的建议。
我的目标是 iOS 14,并使用 swift 5。
编辑 感谢 Witek 的回答,我能够使用 UICollectionViewCompositionalLayout 非常轻松地完成此操作,而且我什至不必订阅更改,只需在我的布局中查询 traitCollection 就足够了。这是我的最终结果:
private func createCompositionalLayout() -> UICollectionViewLayout {
let layout = UICollectionViewCompositionalLayout { (sectionIndex: Int,
layoutEnvironment: NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection? in
let columns = self.traitCollection.preferredContentSizeCategory.isAccessibilityCategory ? 1 : 2
// Define Item Size
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(1.0))
// Create Item
let item = NSCollectionLayoutItem(layoutSize: itemSize)
// Define Group Size
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(150.0))
// Create Group
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitem: item, count: columns)
group.interItemSpacing = .fixed(10.0)
// Create Section
let section = NSCollectionLayoutSection(group: group)
// Configure Section
section.contentInsets = NSDirectionalEdgeInsets(top: 10.0, leading: 10.0, bottom: 10.0, trailing: 10.0)
section.interGroupSpacing = 10
return section
}
return layout
}
您可以观察 UIContentSizeCategory.didChangeNotification
并根据通知中传递的 newValueUserInfoKey
值更改列数(单元格大小)。
@objc private func sizeCategoryDidChange() {
collectionView.reloadData()
}
NotificationCenter.default.addObserver(
self, selector: #selector(sizeCategoryDidChange),
name: UIContentSizeCategory.didChangeNotification, object: nil
)
首选内容大小类别也可以很容易地从 UIApplication.shared
let contentSizeCategory = UIApplication.shared.preferredContentSizeCategory
快捷方式应用程序似乎根据 isAccessibilityCategory
属性 进行布局,以确定当前内容类别是否属于可访问性类别之一
let cellWidth: CGFloat
let padding: CGFloat = 16
if contentSizeCategory.isAccessibilityCategory {
// single column, full width with padding
cellWidth = collectionView.bounds.width - (padding * 2)
} else {
// double column, half width with padding
cellWidth = (collectionView.bounds.width - (padding * 3)) / 2
}
文档: