你如何为组合的 UICollectionViewLayouts 制作 NSCollectionLayoutVisibleItem 的动画?
How do you animate NSCollectionLayoutVisibleItem for compositional UICollectionViewLayouts?
我正在尝试 iOS13 引入的新组合布局 API,它们非常棒 - 但我对一件事特别有疑问,而且关于它的官方文档很少。
我想使用 visibleItemsInvalidationHandler
在 NSCollectionLayoutVisibleItem
对象上执行动画。到目前为止,我已经尝试了两种不同的方法:
- 使用
UIView
属性 动画师
layoutSection.visibleItemsInvalidationHandler = { (visibleItems, offset, env) in
let normalizedOffsetX = offset.x + centeredPadding
let centerPoint = CGPoint(x: normalizedOffsetX + collectionView.bounds.width / 2, y: 20)
visibleItems.forEach({ item in
UIView.animate(withDuration: 0.3) {
item.transform = item.frame.contains(centerPoint) ? .identity : CGAffineTransform(scaleX: 0.9, y: 0.9)
}
})
}
- 使用
CATransaction
个动画师
layoutSection.visibleItemsInvalidationHandler = { (visibleItems, offset, env) in
let normalizedOffsetX = offset.x + centeredPadding
let centerPoint = CGPoint(x: normalizedOffsetX + collectionView.bounds.width / 2, y: 20)
visibleItems.forEach({ item in
CATransaction.begin()
CATransaction.setAnimationDuration(0.3)
CATransaction.setCompletionBlock {
item.transform = item.frame.contains(centerPoint) ? .identity : CGAffineTransform(scaleX: 0.9, y: 0.9)
}
CATransaction.commit()
})
}
这些方法都不起作用 - 然而,虽然不是动画,但我确实看到 UI 上反映的 transform
变化。
我刚刚发现了如何执行此操作,希望这会对其他人有所帮助。关键似乎是在 NSCollectionLayoutVisibleItem
上使用 indexPath
属性 然后从 UICollectionView
检索 UITableViewCell
并在其上执行任何动画。
以下是我最终解决问题的方法:
layoutSection.visibleItemsInvalidationHandler = { (visibleItems, offset, env) in
let normalizedOffsetX = offset.x + centeredPadding
let centerPoint = CGPoint(x: normalizedOffsetX + collectionView.bounds.width / 2, y: 20)
visibleItems.forEach({ item in
guard let cell = collectionView.cellForItem(at: item.indexPath) else { return }
UIView.animate(withDuration: 0.3) {
cell.transform = item.frame.contains(centerPoint) ? .identity : CGAffineTransform(scaleX: 0.9, y: 0.9)
}
})
}
我正在尝试 iOS13 引入的新组合布局 API,它们非常棒 - 但我对一件事特别有疑问,而且关于它的官方文档很少。
我想使用 visibleItemsInvalidationHandler
在 NSCollectionLayoutVisibleItem
对象上执行动画。到目前为止,我已经尝试了两种不同的方法:
- 使用
UIView
属性 动画师
layoutSection.visibleItemsInvalidationHandler = { (visibleItems, offset, env) in
let normalizedOffsetX = offset.x + centeredPadding
let centerPoint = CGPoint(x: normalizedOffsetX + collectionView.bounds.width / 2, y: 20)
visibleItems.forEach({ item in
UIView.animate(withDuration: 0.3) {
item.transform = item.frame.contains(centerPoint) ? .identity : CGAffineTransform(scaleX: 0.9, y: 0.9)
}
})
}
- 使用
CATransaction
个动画师
layoutSection.visibleItemsInvalidationHandler = { (visibleItems, offset, env) in
let normalizedOffsetX = offset.x + centeredPadding
let centerPoint = CGPoint(x: normalizedOffsetX + collectionView.bounds.width / 2, y: 20)
visibleItems.forEach({ item in
CATransaction.begin()
CATransaction.setAnimationDuration(0.3)
CATransaction.setCompletionBlock {
item.transform = item.frame.contains(centerPoint) ? .identity : CGAffineTransform(scaleX: 0.9, y: 0.9)
}
CATransaction.commit()
})
}
这些方法都不起作用 - 然而,虽然不是动画,但我确实看到 UI 上反映的 transform
变化。
我刚刚发现了如何执行此操作,希望这会对其他人有所帮助。关键似乎是在 NSCollectionLayoutVisibleItem
上使用 indexPath
属性 然后从 UICollectionView
检索 UITableViewCell
并在其上执行任何动画。
以下是我最终解决问题的方法:
layoutSection.visibleItemsInvalidationHandler = { (visibleItems, offset, env) in
let normalizedOffsetX = offset.x + centeredPadding
let centerPoint = CGPoint(x: normalizedOffsetX + collectionView.bounds.width / 2, y: 20)
visibleItems.forEach({ item in
guard let cell = collectionView.cellForItem(at: item.indexPath) else { return }
UIView.animate(withDuration: 0.3) {
cell.transform = item.frame.contains(centerPoint) ? .identity : CGAffineTransform(scaleX: 0.9, y: 0.9)
}
})
}