如何实现平移手势以折叠展开的collectionview单元?

时间:2019-05-24 15:58:45

标签: ios swift xcode uicollectionview gesture

我正在开发一个具有UICollectionView的应用程序,因此,当我在集合视图中点击一个单元格时,它会展开以填充屏幕并显示文本;当我再次轻按单元内部时,它会折叠回原来的大小。我想在扩展的单元格上执行平移手势,以便当我在屏幕上向下拖动时将其折叠。我还计划使扩展单元格内的内容可滚动,所以我不希望平移手势干扰单元格内的滚动,而仅当我一直向上滚动到单元格内时才被激活。

我尝试查找有关平移手势的教程,但是数量很少,我发现没有一个可以解决我的问题。我试图自己找到一种实现平移手势的方法,但是如果我将其放置在Cell类或ViewController类中,则会感到困惑。

//The view controller class
class MainView: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UIViewControllerTransitioningDelegate {

    @IBOutlet weak var collectionView: UICollectionView!

    //Here is the animation implementation for expanding and collapsing the cell.
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {


        let dampingRatio: CGFloat = 0.8
        let initialVelocity: CGVector = CGVector.zero
        let springParameters: UISpringTimingParameters = UISpringTimingParameters(dampingRatio: dampingRatio, initialVelocity: initialVelocity)
        let animator = UIViewPropertyAnimator(duration: 0.5, timingParameters: springParameters)


        self.view.isUserInteractionEnabled = false

        if let selectedCell = expandedCell {
            isStatusBarHidden = false

            animator.addAnimations {
                selectedCell.collapse()

                for cell in self.hiddenCells {
                    cell.show()
                }
            }

            animator.addCompletion { _ in
                collectionView.isScrollEnabled = true

                self.expandedCell = nil
                self.hiddenCells.removeAll()
            }

        } else {
            isStatusBarHidden = true

            collectionView.isScrollEnabled = false

            let selectedCell = collectionView.cellForItem(at: indexPath)! as! UserCell
            let frameOfSelectedCell = selectedCell.frame

            expandedCell = selectedCell
            hiddenCells = collectionView.visibleCells.map { $0 as! UserCell }.filter { $0 != selectedCell }

            animator.addAnimations {
                selectedCell.expand(in: collectionView)

                for cell in self.hiddenCells {
                    cell.hide(in: collectionView, frameOfSelectedCell: frameOfSelectedCell)
                }
            }
        }


        animator.addAnimations {
            self.setNeedsStatusBarAppearanceUpdate()
        }

        animator.addCompletion { _ in
            self.view.isUserInteractionEnabled = true
        }

        animator.startAnimation()
    }

    func shadowView(layer: CALayer, cornerRadius: CGFloat) {
        layer.cornerRadius = cornerRadius
        layer.borderWidth = 10.0
        layer.borderColor = UIColor.clear.cgColor
        layer.masksToBounds = true;

        layer.shadowColor = UIColor.black.cgColor
        layer.shadowOffset = CGSize(width:0,height: 2.0)
        layer.shadowRadius = 2.0
        layer.shadowOpacity = 0.3
        layer.masksToBounds = false;
        layer.shadowPath = UIBezierPath(roundedRect:layer.bounds, cornerRadius:layer.cornerRadius).cgPath
    }
}

//The cell class with the expand(), collapse(), hide() and show() methods
class UserCell: UICollectionViewCell {

    func hide(in collectionView: UICollectionView, frameOfSelectedCell: CGRect) {
        initialFrame = self.frame

        let currentY = self.frame.origin.y
        let newY: CGFloat

        if currentY < frameOfSelectedCell.origin.y {
            let offset = frameOfSelectedCell.origin.y - currentY
            newY = collectionView.contentOffset.y - offset
        } else {
            let offset = currentY - frameOfSelectedCell.maxY
            newY = collectionView.contentOffset.y + collectionView.frame.height + offset
        }

        self.frame.origin.y = newY

        layoutIfNeeded()
    }

    func show() {
        self.frame = initialFrame ?? self.frame

        initialFrame = nil

        layoutIfNeeded()
    }

    // MARK: - Expanding/Collapsing Logicl
    func expand(in collectionView: UICollectionView) {
        initialFrame = self.frame
        initialCornerRadius = self.contentView.layer.cornerRadius

        self.contentView.layer.cornerRadius = 0
        self.frame = CGRect(x: 0, y: collectionView.contentOffset.y, width: collectionView.frame.width, height: collectionView.frame.height)

        layoutIfNeeded()
    }

    func collapse() {
        self.contentView.layer.cornerRadius = initialCornerRadius ?? self.contentView.layer.cornerRadius
        self.frame = initialFrame ?? self.frame

        initialFrame = nil
        initialCornerRadius = nil

        layoutIfNeeded()
    }
}

我没有包含类的不必要部分以保持代码简洁。我只需要找出一种实现平移手势的方法,以使其平移已经展开的单元格。您可以在以下位置找到我的应用程序的片段:https://imgur.com/a/3fyzcds 如果您熟悉移动Appstore的“今天”页面的结构方式,可以在其中展开UICollectionViewCell,然后向下拖动以将其折叠起来,那么我正在寻找基本相同的结果。

0 个答案:

没有答案