【问题标题】:How to animate a UICollectionView cell selection如何为 UICollectionView 单元格选择设置动画
【发布时间】:2018-08-22 01:33:48
【问题描述】:

UICollectionView 的这些方法的animated 参数有什么作用:

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

我知道我可以使用UICollectionViewLayout 对象为更改设置动画。我也知道我可以使用UICollectionViewDelegatedidSelectdidDeselect 方法来获取选定的单元格并应用动画。但我找不到任何关于上述animated 参数如何影响动画的信息。它会以任何方式影响布局动画吗?我的目标是创建一个UICollectionView 子类,并允许消费者自定义在内部调用上述两种方法时是否应用动画。但我不知道这些方法控制什么动画。

【问题讨论】:

    标签: ios swift animation uicollectionview uicollectionviewcell


    【解决方案1】:

    我建议用动画覆盖UICollectionViewCellisHighlighted 属性。这样,如果用户点击一个单元格并停下来思考下一步该做什么,动画状态将被保留。

        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
            })
        }
    

    【讨论】:

      【解决方案2】:

      UICollectionViewselectItem(at:animated:scrollPosition:) 中的animated 确定要选择的项目(如果不在视图中或已在所需位置)是否应以动画方式滚动到。
      如果它在视图中,那么这个 animated 属性实际上并没有做任何事情,afaik。
      deselectItem(at:animated:) 中的 animated 相同。它什么也不做,就在那里。

      我看到影响布局引擎的唯一一件事是如果collectionView 滚动并且您在didSelectItemAt 中有动画,那么它将使这些动画无效。您将不得不延迟单元格中发生的动画(请参阅此答案中的最后一个示例)


      正如您已经知道的那样,但对于其他人来说,如果您想为单元格选择事件设置动画,那么您必须在 collectionView(_:didSelectItemAt:) 委托中自己完成。

      例子:

      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
              })
          }
      
      }
      

      如果用户点击一个单元格,上述方法很好,但如果您以编程方式调用selectItem(at:animated:scrollPosition:),它不会触发上述collectionView(_:didSelectItemAt:) 委托,您需要显式调用它来运行您的选择动画。

      示例(上一个的附加):

      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)
          }
      }
      

      【讨论】:

      • 谢谢!我将[] 传递给scrollPosition,所以当我切换animated 参数时我没有注意到任何变化。我认为它影响了一些选择动画。我没有想到它实际上会为滚动设置动画。
      • @Hash88 哈哈,发生了。但我很高兴至少在某种程度上提供了帮助:)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-17
      • 2021-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多