Как вы анимируете NSCollectionLayoutVisibleItem для композиционного UICollectionViewLayouts? - PullRequest
1 голос
/ 05 мая 2020

Я пробую новые API-интерфейсы композиционного макета, представленные в iOS13, они довольно хороши, но у меня проблема, в частности, с одной вещью, и по этому поводу очень мало официальной документации. Я хочу выполнить анимацию для объекта 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)
         }
    })
}
Использование 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()
    })
}

Ни один из этих подходов не работает - однако, хотя и без анимации, я вижу transform изменения, отраженные в пользовательском интерфейсе.

1 Ответ

1 голос
/ 05 мая 2020

Я только что узнал, как это сделать, и, надеюсь, это поможет кому-то другому. Ключ, похоже, состоит в том, чтобы использовать свойство 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)
           }
     })
}
...