Как реализовать жест панорамирования, чтобы свернуть ячейку расширенного представления коллекции? - PullRequest
0 голосов
/ 24 мая 2019

Я работаю над приложением, которое имеет 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 Если вы знакомы с тем, как структурирована сегодняшняя страница в мобильном магазине приложений, где вы можете развернуть UICollectionViewCell, а затем перетащить его вниз, чтобы свернуть, я в основном ищу тот же результат.

...