Поддержка масштабирования и прокрутки UICollectionView - PullRequest
0 голосов
/ 26 ноября 2018

У меня есть требование для поддержки масштабирования в UICollectionView.

Требования:

  1. После увеличения он должен поддерживать просмотр скрытой области UICollectionViewCell (область вне области просмотра) с помощью горизонтальной и вертикальной прокрутки.
  2. ПослеУменьшить / уменьшить, он должен поддерживать выбор UICollectionViewCell и способен прокручивать UICollectionView (в основном поведение UICollectionView по умолчанию при возвращении к состоянию без масштабирования.).

Список пробованных подходов:

  1. Добавлен GestureRecognizer

a.Добавлен UIPinchGestureRecognizer для преобразования UICollectionView по масштабу.б.После увеличения масштаба было невозможно переместить UICollectionViewcell для просмотра скрытой области.с.Добавлен UIPanGestureRecognizer для перемещения центра UICollectionView d.Работало нормально, чтобы переместить UICollectionView.е.Теперь мы не можем выбрать UICollectionViewCell и не можем прокрутить UICollectionView.

Добавлен UICollectionView внутри UIScrollView

a.Добавлен UIScrollView с делегатами.б.Добавлен UICollectionView в качестве вложенного представления UIScrollView c.Уменьшение не происходит, потому что UICollectionView (унаследованный UIScrollView) использует жест увеличения

Добавлены UIColectionView и UIScrollView как братья и сестры

a.Добавлены UIScrollView и UICollectionView для родителя.б.Вывести UIScrollView на передний план.с.Zoom работает, но не может панорамировать, чтобы увидеть скрытую область.

Пожалуйста, предложите, если есть какой-либо способ исправить вышеуказанные подходы или лучшую стратегию для достижения увеличения в collectionView.

1 Ответ

0 голосов
/ 28 марта 2019

Я решил эту проблему с помощью UIScrollView и UICollectionViewLayout подкласса.

1) поместил UIScrollView поверх UICollectionView с таким же фреймом.

 self.view.addSubview(scrollView)
 scrollView.addSubview(dummyViewForZooming)
 scrollView.frame = collectionView.frame
 scrollView.bouncesZoom = false
 scrollView.minimumZoomScale = 0.5
 scrollView.maximumZoomScale = 3.0

2) Установите contentSizeUIScrollView и zoomingView должны совпадать с UICollectionView

  override func viewDidLayoutSubviews() {
    super.viewWillLayoutSubviews()

    scrollView.contentSize = layout.collectionViewContentSize
    dummyViewForZooming.frame = CGRect(origin: .zero, size: layout.collectionViewContentSize)
    scrollView.frame = collectionView.frame
  }

3) Удалите все распознаватели жестов из UICollectionView и добавьте делегат для UIScrollView.Добавьте распознаватель жестов касания к UIScrollview

    collectionView.gestureRecognizers?.forEach {

        collectionView.removeGestureRecognizer($0)

    }
    let tap = UITapGestureRecognizer.init(target: self, action: #selector(scrollViewWasTapped(sender:)))
    tap.numberOfTapsRequired = 1
    scrollView.addGestureRecognizer(tap)


    scrollView.delegate = self

4) Когда ScrollView прокручивает или увеличивает масштаб, установите contentOffset UICollectionView таким же, как ScrollView contentOffset, установите layoutScale вашего UICollectionViewLayout в качестве zoomscaleи сделать недействительным макет.

func scrollViewDidZoom(_ scrollView: UIScrollView) {

    if let layout = self.layout, layout.getScale() != scrollView.zoomScale {
        layout.layoutScale = scrollView.zoomScale
        self.layout.invalidateLayout()
        collectionView.contentOffset = scrollView.contentOffset
    }
}

func viewForZooming(in scrollView: UIScrollView) -> UIView? {
    return dummyViewForZooming
}

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    collectionView.contentOffset = scrollView.contentOffset

}

5) переопределить метод prepare в UICollectionViewLayout, отсканировать все ваши layoutAttributes и установить преобразование:

    attribute.transformedFrame = attribute.originalFrame.scale(layoutScale)
    let ts = CGAffineTransform(scaleX: layoutScale, y: layoutScale)
        attribute.transform = ts

    let xDifference = attribute.frame.origin.x - attribute.transformedFrame.origin.x
    let yDifference = attribute.frame.origin.y - attribute.transformedFrame.origin.y

    let t1 = CGAffineTransform(translationX: -xDifference, y: -yDifference)
    let t = ts.concatenating(t1)
        attribute.transform = t

6) убедиться, что вы масштабируете размер содержимого collectionView:

override var collectionViewContentSize: CGSize  {
        return CGSize(width: width * layoutScale, height: height * layoutScale)
    } 

7) Перехватывать касания из распознавателя жестов касания и преобразовывать отображаемое местоположение в точку в представлении коллекции, затем вы можете получить indexPath этой ячейки с помощью indexPathForItem (point :) и выбрать ячейку илипередавать события базовым представлениям ячейки и т. д.

надеюсь, это поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...