Ios UICollectionViewCell上的比例转换
我有一个垂直滚动的集合视图,我想在滚动发生时使中心单元格变大 我在收藏视图中使用无限滚动 以下是我的自定义流布局:Ios UICollectionViewCell上的比例转换,ios,swift,uicollectionview,uicollectionviewcell,uicollectionviewflowlayout,Ios,Swift,Uicollectionview,Uicollectionviewcell,Uicollectionviewflowlayout,我有一个垂直滚动的集合视图,我想在滚动发生时使中心单元格变大 我在收藏视图中使用无限滚动 以下是我的自定义流布局: import Foundation import InfiniteLayout class CustomLayout: InfiniteLayout { public override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
import Foundation
import InfiniteLayout
class CustomLayout: InfiniteLayout {
public override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
let attributes = super.layoutAttributesForElements(in: rect).flatMap {
self.copyLayoutAttributes(from: $0)
}
guard let visibleRect = self.visibleCollectionViewRect() else {
return attributes
}
let centeredOffset = CGPoint(x: visibleRect.midX, y: visibleRect.midY)
for attributes in attributes ?? [] {
let diff = self.scrollDirection == .horizontal ? centeredOffset.x - attributes.center.x : centeredOffset.y - attributes.center.y
let distance = abs(diff)
let tolerance : CGFloat = 0.02
var scale = 1.00 + tolerance - (( distance / centeredOffset.y ) * 0.105)
if(scale > 1.0){
scale = 1.0
}
if(scale < 0.460091){
scale = 0.460091
}
attributes.transform = attributes.transform.scaledBy(x: scale, y: scale)
attributes.alpha = changeSizeScaleToAlphaScale(scale)
}
return attributes
}
func changeSizeScaleToAlphaScale(_ x : CGFloat) -> CGFloat {
let minScale : CGFloat = 0.46
let maxScale : CGFloat = 1.0
let minAlpha : CGFloat = 0.25
let maxAlpha : CGFloat = 1.0
return ((maxAlpha - minAlpha) * (x - minScale)) / (maxScale - minScale) + minAlpha
}
}
这是我滚动到可见单元格的扩展:
extension InfiniteCollectionView {
func scrollToNearestVisibleCollectionViewCell() {
self.decelerationRate = UIScrollView.DecelerationRate.normal
let visibleCenterPositionOfScrollView = Float(self.contentOffset.y + (self.bounds.size.height / 2))
var closestCellIndex = -1
var closestDistance: Float = .greatestFiniteMagnitude
for i in 0..<self.visibleCells.count {
let cell = self.visibleCells[i]
let cellHeight = cell.bounds.size.width
let cellCenter = Float(cell.frame.origin.y + cellHeight / 2)
// Now calculate closest cell
let distance: Float = fabsf(visibleCenterPositionOfScrollView - cellCenter)
if distance < closestDistance {
closestDistance = distance
closestCellIndex = self.indexPath(for: cell)!.row
}
}
if closestCellIndex != -1 {
self.scrollToItem(at: IndexPath(row: closestCellIndex, section: 0), at: .centeredVertically, animated: true)
}
}
}
扩展无限集合视图{
func scrollToNearestVisibleCollectionViewCell()函数{
self.decelerationRate=UIScrollView.decelerationRate.normal
让visibleCenterPositionOfScrollView=Float(self.contentOffset.y+(self.bounds.size.height/2))
var closestCellIndex=-1
var closestDistance:Float=.greatestfinitemagnity
对于0中的i..我不确定这是否是最好的方法
在收集视图
中间做一个var跟踪索引
var index = IndexPath()
在VIEWDIDLAUT子视图中,一旦计算出了已配置的布局
无效,则检查中间的单元格。
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let center = self.view.convert(collectionView.center, to: collectionView)
index = collectionView.indexPathForItem(at: center) ?? IndexPath(item: 0, section: 0)
collectionView.collectionViewLayout.invalidateLayout()
}
然后在SizeFormitem
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
if index.count != 0 {
if index.item == indexPath.item {
return CGSize(width: collectionView.frame.size.width, height: 100)
}
}
return CGSize(width: collectionView.frame.size.width, height: 50)
}
然后在scrollviewdidscroll中再次调用ViewDidLayoutSubView,以便重新计算居中元素并更改项目大小
func scrollViewDidScroll(_ scrollView: UIScrollView) {
viewDidLayoutSubviews()
}
谢谢,但是我通过定制我的流程布局来实现这个概念!这是唯一正确的方法
func scrollViewDidScroll(_ scrollView: UIScrollView) {
viewDidLayoutSubviews()
}