你如何为组合 UICollectionViewLayouts 动画 NSCollectionLayoutVisibleItem?

Cha*_*kle 1 cgaffinetransform ios uicollectionview swift ios13

我正在尝试使用 iOS13 引入的新的组合布局 API,它们非常棒 - 但我有一个特别的问题,关于它的官方文档很少。

我正在寻找NSCollectionLayoutVisibleItem使用visibleItemsInvalidationHandler. 到目前为止,我已经尝试了两种不同的方法:

  1. 使用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)
         }
    })
}
Run Code Online (Sandbox Code Playgroud)
  1. 使用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()
    })
}
Run Code Online (Sandbox Code Playgroud)

这些方法都不起作用 - 然而,虽然没有动画,但我确实看到transform了 UI 上反映的变化。

Cha*_*kle 6

我刚刚发现了如何做到这一点,希望这会帮助其他人。关键似乎是使用 上的indexPath属性NSCollectionLayoutVisibleItem,然后UITableViewCell从 中检索UICollectionView并在其上执行任何动画。

这是我最终解决问题的方法:

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)
           }
     })
}
Run Code Online (Sandbox Code Playgroud)