简体   繁体   English

如何为 UICollectionView 单元格选择设置动画

[英]How to animate a UICollectionView cell selection

What does the animated argument of these methods of UICollectionView do: UICollectionView的这些方法的animated参数有什么作用:

  •  selectItem(at indexPath: IndexPath?, animated: Bool, scrollPosition: UICollectionViewScrollPosition)`
  •  deselectItem(at indexPath: IndexPath, animated: Bool)

I know I can use the UICollectionViewLayout object to animate changes.我知道我可以使用UICollectionViewLayout对象来为更改设置动画。 I also know that I can use didSelect and didDeselect methods of the UICollectionViewDelegate to get the selected cell and apply animations.我也知道,我可以使用didSelectdidDeselect的方法UICollectionViewDelegate获取所选单元格并应用动画。 But I can't find any information about how the above animated argument affects animations.但是我找不到有关上述animated参数如何影响动画的任何信息。 Does it affect the layout animations in any way?它会以任何方式影响布局动画吗? My goal is to create a UICollectionView subclass and allow the consumer to customize whether animations apply when the above two methods are called internally.我的目标是创建一个UICollectionView子类,并允许消费者自定义在内部调用上述两种方法时是否应用动画。 But I don't know what animations those methods control.但我不知道这些方法控制什么动画。

The animated in UICollectionView 's selectItem(at:animated:scrollPosition:) determines whether the item to-be-selected, if not in view or at required position already, should be scrolled to in an animated fashion or not.所述animatedUICollectionViewselectItem(at:animated:scrollPosition:)以动画方式与否确定是否项待选择的,如果不是在视图或所需的位置早已,应滚动到。
If it's in view then this animated property doesn't really do anything, afaik.如果它在视野中,那么这个animated属性并没有真正做任何事情,afaik。
Same for the animated in deselectItem(at:animated:) .deselectItem(at:animated:)animated相同。 It doesn't do anything and is simply there.它什么都不做,就在那里。

The only thing I see affecting the layout engine is if the collectionView scrolls and you have animations in the didSelectItemAt then it will render these animations ineffective.我看到的唯一影响布局引擎的是,如果collectionView滚动并且您在didSelectItemAt有动画,那么它会使这些动画无效。 You would have to delay the animations occurring in the cell (see last example in this answer)您将不得不延迟单元格中发生的动画(请参阅此答案中的最后一个示例)


As you already know but for others, if you want to animate the cell selection event then you will have to do it yourself in the collectionView(_:didSelectItemAt:) delegate.正如您已经知道的,但对于其他人,如果您想为单元格选择事件设置动画,那么您必须在collectionView(_:didSelectItemAt:)委托中自己完成。

Example:示例:

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    let cell = collectionView.cellForItem(at: indexPath)

    //Briefly fade the cell on selection
    UIView.animate(withDuration: 0.5,
                   animations: {
                    //Fade-out
                    cell?.alpha = 0.5
    }) { (completed) in
        UIView.animate(withDuration: 0.5,
                       animations: {
                        //Fade-out
                        cell?.alpha = 1
        })
    }

}

The above is fine if the user taps on a cell but if you programmatically call selectItem(at:animated:scrollPosition:) , it won't trigger the above collectionView(_:didSelectItemAt:) delegate and you would need to explicitly call it to run your selection animation.如果用户点击单元格,则上述内容很好,但如果您以编程方式调用selectItem(at:animated:scrollPosition:) ,则不会触发上述collectionView(_:didSelectItemAt:)委托,您需要明确调用它运行您的选择动画。

Example (Add-on to previous):示例(上一个的附加组件):

func doSelect(for aCollectionView: UICollectionView,
              at indexPath: IndexPath) {
    aCollectionView.selectItem(at: indexPath,
                               animated: true,
                               scrollPosition: .centeredVertically)

    //DispatchQueue after sometime because scroll animation renders
    //the animation block in `collectionView(_:didSelectItemAt:)` ineffective
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.27) { [weak self] in
        self?.collectionView(aCollectionView,
                             didSelectItemAt: indexPath)
    }
}

I would suggest overriding isHighlighted property of UICollectionViewCell with animation.我建议重写isHighlighted财产UICollectionViewCell动画。 That way if a user taps on a cell and stops to think what to do next, the animation state will be preserved.这样,如果用户点击一个单元格并停下来思考下一步要做什么,动画状态将被保留。

    override var isHighlighted: Bool {
        didSet {
            toggleIsHighlighted()
        }
    }

    func toggleIsHighlighted() {
        UIView.animate(withDuration: 0.1, delay: 0, options: [.curveEaseOut], animations: {
            self.alpha = self.isHighlighted ? 0.9 : 1.0
            self.transform = self.isHighlighted ?
                CGAffineTransform.identity.scaledBy(x: 0.97, y: 0.97) :
                CGAffineTransform.identity
        })
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM