每当出现新单元格时,将 UICollectionView 单元格垂直和水平连续居中
Continuously center UICollectionView cells both vertically and horizontally whenever new ones appear
设置:
我目前有一个 UICollectionView
是一堆用于模拟 Apple Watch 主屏幕 UI 的单元格圆圈。我是通过关注 this guide 做到的。如果您没有阅读这篇文章或它由于某种原因而下降,它基本上是一个 UI圆圈的 CollectionView,当您将它们从中心滚动时,外部圆圈会按比例缩小。
问题:
我希望气泡动态弹出,这样每当用户获得奖励时,奖励 "pops" 即动画化,从 0 缩放到 1。但是,我希望可以有任何单元格总是居中。因此,例如,当用户从 1 个奖励跳到两个时,我希望第一个移动到左边,同时新的弹出。
我尝试过的:
我已经尝试实施 UICollectionView
的 insetForSectionAt
方法,但它似乎不起作用。我怀疑这是因为 CollectionView 不是 FlowLayout
。我试着把它变成一个,但我最终崩溃了一切......
代码:
这是我实现的,以防万一文章失败。 (为便于阅读而压缩):
class CollectionViewLayout: UICollectionViewLayout {
//Invalidate the layout every time the bounds change so we can do the cool changes
override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
return true
}
override var collectionViewContentSize: CGSize {
return CGSize(width: self.itemSize * CGFloat(COLS),
height: self.itemSize * CGFloat(ROWS))
}
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
var attributes: [UICollectionViewLayoutAttributes] = []
for i in 0..<cellCount {
let indexPath = IndexPath(item: i, section: 0)
attributes.append(self.layoutAttributesForItem(at: indexPath)!)
}
return attributes
}
override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
var attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath)
// **Code where I create "z" variable by using equation in article, where "z" is just a value [0,1] that determines cell's scale**
// **More code where I Calculate "x" and "y" based on indexPath like in article**
//Set the cell's attributes:
attributes.transform = CGAffineTransform(scaleX: z, y: z)
attributes.size = CGSize(width: self.itemSize, height: self.itemSize)
attributes.center = CGPoint(x: x, y: y)
return attributes
}
}
我认为解决您的问题的方法是将集合视图滚动到您希望居中的奖励的 indexPath,因为集合视图是滚动视图的子类。您可以通过以下方式将集合视图滚动到项目:
collectionView?.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
其中 indexPath 是您要滚动到的 indexPath。这会自动为您的滚动设置动画,但是如果您想自定义,您可以调用 UIView.animate 函数
设置:
我目前有一个 UICollectionView
是一堆用于模拟 Apple Watch 主屏幕 UI 的单元格圆圈。我是通过关注 this guide 做到的。如果您没有阅读这篇文章或它由于某种原因而下降,它基本上是一个 UI圆圈的 CollectionView,当您将它们从中心滚动时,外部圆圈会按比例缩小。
问题:
我希望气泡动态弹出,这样每当用户获得奖励时,奖励 "pops" 即动画化,从 0 缩放到 1。但是,我希望可以有任何单元格总是居中。因此,例如,当用户从 1 个奖励跳到两个时,我希望第一个移动到左边,同时新的弹出。
我尝试过的:
我已经尝试实施 UICollectionView
的 insetForSectionAt
方法,但它似乎不起作用。我怀疑这是因为 CollectionView 不是 FlowLayout
。我试着把它变成一个,但我最终崩溃了一切......
代码:
这是我实现的,以防万一文章失败。 (为便于阅读而压缩):
class CollectionViewLayout: UICollectionViewLayout {
//Invalidate the layout every time the bounds change so we can do the cool changes
override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
return true
}
override var collectionViewContentSize: CGSize {
return CGSize(width: self.itemSize * CGFloat(COLS),
height: self.itemSize * CGFloat(ROWS))
}
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
var attributes: [UICollectionViewLayoutAttributes] = []
for i in 0..<cellCount {
let indexPath = IndexPath(item: i, section: 0)
attributes.append(self.layoutAttributesForItem(at: indexPath)!)
}
return attributes
}
override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
var attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath)
// **Code where I create "z" variable by using equation in article, where "z" is just a value [0,1] that determines cell's scale**
// **More code where I Calculate "x" and "y" based on indexPath like in article**
//Set the cell's attributes:
attributes.transform = CGAffineTransform(scaleX: z, y: z)
attributes.size = CGSize(width: self.itemSize, height: self.itemSize)
attributes.center = CGPoint(x: x, y: y)
return attributes
}
}
我认为解决您的问题的方法是将集合视图滚动到您希望居中的奖励的 indexPath,因为集合视图是滚动视图的子类。您可以通过以下方式将集合视图滚动到项目:
collectionView?.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
其中 indexPath 是您要滚动到的 indexPath。这会自动为您的滚动设置动画,但是如果您想自定义,您可以调用 UIView.animate 函数