美文网首页swift开发技巧iOSUI
Swift 3.1 - 在 UICollectionView 中

Swift 3.1 - 在 UICollectionView 中

作者: 张嘉夫 | 来源:发表于2017-05-04 17:36 被阅读502次

    在 App 中用 UICollectionView 负责显示的时候,可能会希望用户按住单元格时,所有单元格都开始抖动,就像我们在主屏删除 App 时,所有图标都会开始抖动。所以如何实现这个功能呢?

    首先声明变量:

    var p: CGPoint?
    var longPressed = false {
            didSet {
                
                if oldValue != longPressed {
                    collectionView?.reloadData()
                }
                
            }
        }
    

    viewDidLoad 中给 collectionView添加 UILongPressGestureRecognizerUITapGestureRecognizer,因为我们希望在长按时抖动单元格:

    override func viewDidLoad() {
            super.viewDidLoad()
            
              // 为 collection view cell 添加 gesture recognizer
            let lpgr = UILongPressGestureRecognizer(target: self, action: #selector(CollectionViewController.handleLongPress(_:)))
            collectionView?.addGestureRecognizer(lpgr)
            
            lpgr.delaysTouchesBegan = true
            
              // 用于在点击单元格外部时取消动画
            let tap = UITapGestureRecognizer(target: self, action: #selector(CollectionViewController.handleTap(_:)))
            collectionView?.addGestureRecognizer(tap)
        }
    

    接下来实现 handleLongPress:。长按 collectionViewCell时会得到用户按住的单元格的 (x,y) 坐标,我们将其存储在 p 点中。

    根据这个点,就能获取相应 cell 的 indexPath

              p = gestureRecognizer.location(in: collectionView) // 在 p 点存储用户点击的单元格的 (x,y) 坐标
            if let p = p, let indexPath = collectionView?.indexPathForItem(at: p) {
                
            }
    

    现在,使用 CABasicAnimationQuartzCore 框架给被点击的单元格赋予动画。同时要显示单元格的 deleteButton

    借助 handleTap:,在点击 collectionViewCell 外部时可以取消动画。

          func handleLongPress(_ gestureRecognizer: UILongPressGestureRecognizer) {
            p = gestureRecognizer.location(in: collectionView)
            if let p = p, let _ = collectionView?.indexPathForItem(at: p) {
                longPressed = true
            }
            
        }
        
        func handleTap(_ gestureRecognizer: UITapGestureRecognizer) {
            if gestureRecognizer.state != .ended {
                return
            }
            p = gestureRecognizer.location(in: collectionView)
            if let p = p, collectionView?.indexPathForItem(at: p) == nil {
                longPressed = false
            }
        }
    

    根据被选中的单元格,删除相应的项目:

    func deleteItem() {
            
          let indexPath = self.collectionView?.indexPathForItem(at: p)
          //根据这里的 `indexpath` 删除 collectionViewArray 中的项目
          //或者如果在访问数据库以显示 collectionView,可以比较根据 `indexPath` 获取到的值和数据库的值,然后将其删除
            
          //删除后 reload collectionView
        }
    

    reload collection view 之后,cellForItemAtIndexPath: 看起来会像这样:

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! CollectionViewCell
        
            // Configure the cell
            if longPressed {
                cell.deleteButton.isHidden = false
                cell.deleteButton.addTarget(self, action: #selector(CollectionViewController.deleteItem), for: .touchUpInside)
                let anim = CABasicAnimation(keyPath: "transform.rotation")
                anim.toValue = 0
                anim.fromValue = Double.pi/32
                anim.duration = 0.1
                anim.repeatCount = MAXFLOAT
                anim.autoreverses = true
    //            cell.layer.shouldRasterize = true
                cell.layer.add(anim, forKey: "SpringboardShake")
            }else {
                cell.deleteButton.isHidden = true
                cell.layer.removeAllAnimations()
            }
        
            return cell
        }
    

    相关文章

      网友评论

      本文标题:Swift 3.1 - 在 UICollectionView 中

      本文链接:https://www.haomeiwen.com/subject/zbrdtxtx.html