【问题标题】:Zoom and Scroll support UICollectionView缩放和滚动支持 UICollectionView
【发布时间】:2019-04-28 02:19:57
【问题描述】:

我需要在 UICollectionView 中支持缩放。

要求:

  1. 放大后必须支持横向和纵向滚动查看UICollectionViewCell的隐藏区域(视口外区域)。
  2. 缩小/缩小后,它必须支持 UICollectionViewCell 的选择并能够滚动 UICollectionView(基本上是返回无缩放状态时的默认 UICollectionView 行为。)。

尝试的方法列表:

  1. 添加了 GestureRecognizer

一个。添加了 UIPinchGestureRecognizer 以按比例转换 UICollectionView。 湾。放大后,无法移动 UICollectionViewcell 来查看隐藏区域。 C。添加了 UIPanGestureRecognizer 以移动 UICollectionView 的中心 d。移动 UICollectionView 工作正常。 e.现在我们无法选择 UICollectionViewCell 也无法滚动 UICollectionView。

  1. 在 UIScrollView 中添加了 UICollectionView

一个。添加了带有代表的 UIScrollView。 湾。添加 UICollectionView 作为 UIScrollView 的子视图 C。缩小没有发生,因为 UICollectionView(由 UIScrollView 继承)消耗了缩放手势

  1. 添加了 UIColectionView 和 UIScrollView 作为兄弟姐妹

一个。将 UIScrollView 和 UICollectionView 添加到父级。 湾。将 UIScrollView 放在前面。 C。缩放正在工作,但无法平移以查看隐藏区域。

请建议是否有任何方法可以解决上述方法或实现放大 collectionView 的更好策略。

【问题讨论】:

  • 一天结束时,您的 UICollectionView 必须水平或垂直滚动​​。当您放大它时,它将无法双向滚动。我认为您的缩放功能基本上必须根据您的放大程度来更改您显示的单元格的大小或顶部。您可以在 sizeForCell 函数中调整单元格的大小,或者您可以有多个 Collection View Cell 类并根据您想要的缩放级别显示相关的类

标签: ios objective-c uiscrollview uicollectionview


【解决方案1】:

我已经使用 UIScrollView 和 UICollectionViewLayout 子类解决了这个问题。

1) 在 UICollectionView 的顶部放置一个 UIScrollView 与相同的框架。

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

2) 设置 UIScrollView 和 zoomingView 的 contentSize 与 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 滚动或缩放时,将 UICollectionView 的 contentOffset 设置为与 ScrollView contentOffset 相同,将你的 UICollectionViewLayout 的 layoutScale 设置为 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) 覆盖 UICollectionViewLayout 中的 prepare 方法,扫描所有 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) 从点击手势识别器拦截点击并将视图中的位置转换为集合视图中的一个点,然后您可以使用 indexPathForItem(point:) 获取该单元格的 indexPath 并选择该单元格或将事件传递给单元格的底层视图等。

希望对你有帮助

【讨论】:

    猜你喜欢
    • 2016-09-25
    • 2018-06-15
    • 2012-07-25
    • 2017-05-20
    • 1970-01-01
    • 1970-01-01
    • 2013-04-06
    • 2011-12-13
    • 2013-10-05
    相关资源
    最近更新 更多