如何在水平collectionview中设置不同的单元格高度和宽度
Posted
技术标签:
【中文标题】如何在水平collectionview中设置不同的单元格高度和宽度【英文标题】:How to set different height and width of cells in horizontal collectionview 【发布时间】:2016-12-20 05:41:38 【问题描述】:我有一个水平集合视图,它一次显示 5 个单元格,我已经通过 sizeForItemAt 进行了调整:
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize
return CGSize(width: (self.numberCollectionView?.bounds.size.width)!/5 - 3, height: (self.numberCollectionView?.bounds.size.width)!/5 - 3 )
但是这 5 个单元格的宽度和高度会不同,并且有一个比例。所以 center 项目将占据整个尺寸的 40%,2nd 和 3rd 项目将占据 20% 的尺寸,而 >1st 和 5th 将占大小的 10%。根据这个比率,项目大小会在 scroll 上发生变化。这些项目都是标签。
编辑: 在我的情况下,与建议的问题和 *** 中的其他问题不同,只有一行,我有自定义 UICollectionViewFlowLayout 来处理单元格滚动
【问题讨论】:
How Can I Animate the Size of A UICollectionViewCell on Scroll so the middle one is largest?的可能重复 那个问题甚至没有正确答案 根据CGSize
中的返回值,所有单元格将是完美的正方形,一次只显示5个提供单元格的项目间距是 3。
是的,但我不知道如何将可见中心元素的大小更改为整个宽度的 40%
@Fay007 您可以根据您的 indexpath 设置所有单元格大小就像在此方法中您可以检查 indexpath.row == 0 然后返回此
【参考方案1】:
UICollectionViewFlowLayout 处理单元格滚动:
class CustomCollectionViewFlowLayout: UICollectionViewFlowLayout
override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint
var offsetAdjustment = CGFloat.greatestFiniteMagnitude
let horizontalOffset = proposedContentOffset.x
let targetRect = CGRect(x: proposedContentOffset.x, y: 0, width: self.collectionView!.bounds.size.width, height: self.collectionView!.bounds.size.height)
for layoutAttributes in super.layoutAttributesForElements(in: targetRect)!
let itemOffset = layoutAttributes.frame.origin.x
if (abs(itemOffset - horizontalOffset) < abs(offsetAdjustment))
offsetAdjustment = itemOffset - horizontalOffset
return CGPoint(x: proposedContentOffset.x + offsetAdjustment, y: proposedContentOffset.y)
然后找到CollectionView
的中心单元格:
private func findCenterIndex() -> Int
let center = self.view.convert(numberCollectionView.center, to: self.numberCollectionView)
let row = numberCollectionView!.indexPathForItem(at: center)?.row
guard let index = row else
return 0
self.rating = index
return index
scrollViewDidScroll
transformed 单元格下:
func scrollViewDidScroll(_ scrollView: UIScrollView)
transformCell()
private func transformCell()
let row = findCenterIndex()
var offset : Float = 0.0
for cell in numberCollectionView.visibleCells as! [VotingCell]
if row == numberCollectionView.indexPath(for: cell)?.row
offset = 1.1
cell.label.font = UIFont.boldSystemFont(ofSize: 28.0)
cell.label.textColor = UIColor.black
cell.alpha = 1.0
cell.label.textAlignment = .center
else if row == (numberCollectionView.indexPath(for: cell)?.row)! + 1 || row == (numberCollectionView.indexPath(for: cell)?.row)! - 1
offset = 0.8
cell.label.font = UIFont(name: cell.label.font.fontName, size: 26.0)
cell.label.textColor = UIColor.gray
cell.alpha = 0.8
cell.label.textAlignment = .center
else if row == (numberCollectionView.indexPath(for: cell)?.row)! + 2 || row == (numberCollectionView.indexPath(for: cell)?.row)! - 2
offset = 0.7
cell.label.font = UIFont(name: cell.label.font.fontName, size: 20.0)
cell.label.textColor = UIColor.gray
cell.alpha = 0.8
cell.label.textAlignment = .center
else
offset = 0.00
cell.transform = CGAffineTransform.identity
cell.transform = CGAffineTransform(scaleX: CGFloat(offset), y: CGFloat(offset))
也从viewDidLayoutSubviews
调用transformCell()
进行初始加载。
【讨论】:
我无法理解您代码中的两点。什么来自 [VotingCell] 和 self.rating ?以上是关于如何在水平collectionview中设置不同的单元格高度和宽度的主要内容,如果未能解决你的问题,请参考以下文章
Swift - 在CollectionView中设置不同宽度的单元格之间的固定间距
如何在 collectionView 单元格中设置 NSLayoutConstraint 常量?
如何仅为一个 indexPath.row 项目在 CollectionView 单元格中设置动画?
如何在 Swift 4 中设置从 collectionView 底部到 Input Accessory View 顶部的约束