【问题标题】:Animate cell when pressed using Swift 3使用 Swift 3 按下时为单元格设置动画
【发布时间】:2017-08-12 15:18:06
【问题描述】:

我的问题很简单。我想为 collectionView 中的单元格设置动画。事实上,我想在单元格后面显示一个灰色背景并缩小里面的图像。

与 Pinterest 的效果(几乎)相同:

我曾经在按钮上编写动画,但我从来没有在单元格上这样做过。例如,如何将单元格链接到 touchUpInside 或 TouchDown 操作?

【问题讨论】:

  • 我想在 Touch Down 时启动动作,在 Touch up 内部时释放

标签: swift animation swift3 uicollectionview cell


【解决方案1】:

如果要在触摸单元格时启动动画,可以实现didHighlightItemAt。您可能想在didUnhighlightItemAt 中反转它:

override func collectionView(_ collectionView: UICollectionView, didHighlightItemAt indexPath: IndexPath) {
    UIView.animate(withDuration: 0.5) {
        if let cell = collectionView.cellForItem(at: indexPath) as? CustomCell {            
            cell.imageView.transform = .init(scaleX: 0.95, y: 0.95)
            cell.contentView.backgroundColor = UIColor(red: 0.95, green: 0.95, blue: 0.95, alpha: 1)
        }
    }
}

override func collectionView(_ collectionView: UICollectionView, didUnhighlightItemAt indexPath: IndexPath) {
    UIView.animate(withDuration: 0.5) {
        if let cell = collectionView.cellForItem(at: indexPath) as? CustomCell {
            cell.imageView.transform = .identity
            cell.contentView.backgroundColor = .clear
        }
    }
}

产生:

【讨论】:

  • 不起作用自动布局约束用于单元格中的包装视图
  • 这个例子完全是用自动布局约束完成的。这就是为什么我使用transform 而不是调整frame 的原因,正是因为它不会干扰/冲突自动布局。如果您真的想要,您可以通过调整前导、尾随、顶部和底部约束并为对layoutIfNeeded() 的调用设置动画来实现相同的目的,但这会不必要地复杂。
【解决方案2】:

如果您只需要为特定单元格实现此功能,只需将此代码添加到您的单元格实现中:

override var isHighlighted: Bool {
  didSet {
    UIView.animate(withDuration: 0.5) {
      let scale: CGFloat = 0.9
      self.transform = self.isHighlighted ? CGAffineTransform(scaleX: scale, y: scale) : .identity
    }
  }
}

这与建议 [pgdev][1] 的答案相同,但针对 isHighlighted

【讨论】:

    【解决方案3】:

    Swift 4.2,在 UICollectionViewCell 内

        //MARK:- Events
        override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
            super.touchesBegan(touches, with: event)
            animate(isHighlighted: true)
        }
    
        override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
            super.touchesEnded(touches, with: event)
            animate(isHighlighted: false)
        }
    
        override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
            super.touchesCancelled(touches, with: event)
            animate(isHighlighted: false)
        }
    
        //MARK:- Private functions
        private func animate(isHighlighted: Bool, completion: ((Bool) -> Void)?=nil) {
            let animationOptions: UIView.AnimationOptions = [.allowUserInteraction]
            if isHighlighted {
                UIView.animate(withDuration: 0.5,
                               delay: 0,
                               usingSpringWithDamping: 1,
                               initialSpringVelocity: 0,
                               options: animationOptions, animations: {
                                self.transform = .init(scaleX: 0.96, y: 0.96)
                }, completion: completion)
            } else {
                UIView.animate(withDuration: 0.5,
                               delay: 0,
                               usingSpringWithDamping: 1,
                               initialSpringVelocity: 0,
                               options: animationOptions, animations: {
                                self.transform = .identity
                }, completion: completion)
            }
        }
    

    【讨论】:

    • 工作就像一个魅力
    【解决方案4】:

    试试这个:

    在您的自定义UICollectionViewCell 中,在选择单元格时更改imageView transform,即

    class CollectionViewCell: UICollectionViewCell
    {
        @IBOutlet weak var imageView: UIImageView!
    
        override var isSelected: Bool{
            didSet{
                UIView.animate(withDuration: 2.0) {
                    self.imageView.transform = self.isSelected ? CGAffineTransform(scaleX: 0.9, y: 0.9) : CGAffineTransform.identity
                }
            }
        }
    }
    

    【讨论】:

      【解决方案5】:

      Swift : 4 需要实现自定义UICollectionViewCell,选中单元格时更改contentView OR imageView transform

      override var isSelected: Bool {
                      didSet{
                             UIView.animate(withDuration: 1.0, animations: 
                              {
                                   self.contentView.transform = self.isSelected ? CGAffineTransform(scaleX: 0.95, y: 0.95) : CGAffineTransform.identity
                                   self.contentView.backgroundColor = UIColor(red: 0.95, green: 0.95, blue: 0.95, alpha: 1)
                              }) { (true) in
                              UIView.animate(withDuration: 0.5, animations:
                              {
                                   self.contentView.transform = self.isSelected ?  CGAffineTransform(scaleX: 1.0, y: 1.0) : CGAffineTransform.identity
                                   self.contentView.backgroundColor = UIColor.clear
                              })
                          } 
                       }
                   }
      

      【讨论】:

        【解决方案6】:

        您有多种选择。

        • 您可以实现集合视图委托方法collectionView(:didSelectItemAtIndexPath:) 并将您的代码放在那里。

        • 您可以将点击手势识别器附加到您想要响应点击的视图中。

        • 您可以创建自定义按钮并在其中安装图像,然后照常使用按钮的 IBAction 方法。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-07-04
          • 2017-05-23
          • 1970-01-01
          • 1970-01-01
          • 2015-08-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多