swift - 使用动态大小 uicollectionView 单元格时如何为特定单元格设置大小
问题描述
我正在关注本教程:
https://www.raywenderlich.com/4829472-uicollectionview-custom-layout-tutorial-pinterest
基本上是水平collectionView
输入section 1
和垂直collectionView
输入section 2
我的想法是在第一个单元格中放置一个 collectionView,它的大小应该是:CGSize(width: screen.width, height: 100)
但由于我使用的是链接中的方法,我不知道如何为第一个单元格指定特定大小。这是我尝试过的:
解决方案
免责声明:由于 OP 之前曾问过一个关于如何创建 Pinterest 布局的问题,并且我在评论中建议了 Raywenderlich 教程,我相信 OP 提出的这个问题是该问题的扩展
回答:
查看您添加的设计,我相信您正在尝试添加一个CollectionView
具有水平滚动的作为跨越整个集合视图宽度的第一个单元格。因为你已经继承了UICollectionViewFlowLayout
你需要在prepare
方法本身中处理这种特殊情况
override func prepare() {
// 1
guard
cache.isEmpty,
let collectionView = collectionView
else {
return
}
// 2
let columnWidth = contentWidth / CGFloat(numberOfColumns)
var xOffset: [CGFloat] = []
for column in 0..<numberOfColumns {
xOffset.append(CGFloat(column) * columnWidth)
}
var column = 0
var yOffset: [CGFloat] = .init(repeating: 0, count: numberOfColumns)
// 3
for item in 0..<collectionView.numberOfItems(inSection: 0) {
let indexPath = IndexPath(item: item, section: 0)
let attributes: UICollectionViewLayoutAttributes
let photoHeight = delegate?.collectionView(
collectionView,
heightForPhotoAtIndexPath: indexPath) ?? 180
let height = cellPadding * 2 + photoHeight
let frame: CGRect
if item == 0 {
frame = CGRect(x: 0,
y: yOffset[column],
width: columnWidth,
height: height)
contentHeight = frame.maxY
for column in 0..<numberOfColumns {
yOffset[column] = frame.maxY
}
column = 0
}
else {
// 4
frame = CGRect(x: xOffset[column],
y: yOffset[column],
width: columnWidth,
height: height)
contentHeight = max(contentHeight, frame.maxY)
yOffset[column] = yOffset[column] + height
column = column < (numberOfColumns - 1) ? (column + 1) : 0
}
let insetFrame = frame.insetBy(dx: cellPadding, dy: cellPadding)
attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath)
attributes.frame = insetFrame
cache.append(attributes)
}
}
在您的for item in 0..<collectionView.numberOfItems(inSection: 0) {
我添加了一个特殊条件来处理if item == 0 {
where in 而不是使用列宽,我使用了内容宽度(根据您的设计,您希望第一个单元格覆盖集合视图的整个宽度)
最后在您的委托方法中
extension PhotoStreamViewController: PinterestLayoutDelegate {
func collectionView(
_ collectionView: UICollectionView,
heightForPhotoAtIndexPath indexPath:IndexPath) -> CGFloat {
if indexPath.row == 0 {
return 180 // whatever is the height of first cell
}
return photos[indexPath.item].image.size.height
}
}
一个警告
在您的设计中,我可以看到您添加了两个部分标题Header 1 和Header 2我猜在这种情况下您返回的部分数量至少为 2,但是如果您注意到,本教程侧重于单个部分集合视图
for item in 0..<collectionView.numberOfItems(inSection: 0) {
第 0 部分是硬编码的,如果您想处理多个部分并且可能需要大量修改,则可能必须动态处理它prepare
推荐阅读
- r - R中所有变量的分组图和垂直轴的设置限制不同
- django - 当它嵌套在 Django 中的另一个序列化程序中时,如何在 URL 中过滤序列化程序?
- go - 带有接口的嵌入式结构不起作用
- marklogic - 有没有办法基于现有的 ML 应用服务器反向生成 ml-gradle 项目配置设置?
- arduino - 如何使用直流电机、电流传感器和 arduino uno 构建扭矩控制电路
- single-sign-on - 从其他程序注册 Laravel SSO
- macos - 如何在 PyCharm 中并排打开“Go to implementation”?
- excel - 基于对其他表的选择的 SUMIF 行
- angular - ng-select - 数据未根据 JSON 正确加载
- docker - AIRFLOW 中缺少 CSRF 会话令牌