简体   繁体   English

嵌套的UICollectionView和Responder链

[英]Nested UICollectionView and Responder chain

I have two UICollectionVews 我有两个UICollectionVews

  • One of them (The parent one) is a full-screen-cell paginated collection view. 其中一个(父级之一)是全屏单元格分页集合视图。

  • The other one (The child one) is a filter inside the "page" Both have the same scroll direction 另一个(子级)是“页面”内部的过滤器,两者的滚动方向相同

My problem is that when I'm scrolling the child one, and it reaches the end, the parent one starts moving. 我的问题是,当我滚动子项时,它到达末尾时,父项就开始移动。 And I would like to avoid that. 我想避免这种情况。 I tried many things 我尝试了很多事情

*ScrollView delegates *Touchesbegan * ScrollView代表* Touches开始

Any ideas? 有任何想法吗? Thanks! 谢谢!

I think it's easy . 我认为这很容易。 To set the parent UICollectionView 设置父UICollectionView

collectionView.scrollEnabled = NO;

Or it sounds unreasonable . 否则听起来不合理。 If the parent UICollectionView could scroll, how could you archive your goal? 如果父UICollectionView可以滚动,那么如何归档目标? Because UICollectionView is consisted of the cells (The child one). 因为UICollectionView由单元格组成(子级一个)。 The cell will affect the parent UICollectionView inevitably. 该单元格将不可避免地影响父UICollectionView。

Maybe The child one is located in part of the cell , you could use the 也许孩子一个位于单元格的一部分,您可以使用

UIScrollViewDelegate 's method: scrollViewDidScroll , to set the parent collectionView's scrollEnabled property. UIScrollViewDelegate的方法: scrollViewDidScroll ,用于设置父collectionView的scrollEnabled属性。

I think you prefer this answer. 我认为您更喜欢这个答案。 As we know a pan gesture recognizer is built in UIScrollView. 众所周知,平移手势识别器内置于UIScrollView中。 We could add an other coordinated pan gesture. 我们可以添加其他协调的平移手势。

Because the apple says: 'UIScrollView's built-in pan gesture recognizer must have its scroll view as its delegate.' 因为苹果说:“ UIScrollView的内置平移手势识别器必须将其滚动视图作为其委托。”

        let pan = UIPanGestureRecognizer(target: self, action: #selector(ViewController.panGestureRecognizerAction(recognizer:)))
          pan.delegate = self
          mainScrollView.addGestureRecognizer(pan)

          func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, 
                                shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
                return true
            }
     // So we can get the argus of the pan gesture while not affecting the scroll 
     after the setting. 

            var mainScrollEnabled = false
            var subScrollEnabled = false
    // Then we define two BOOL values to identify the scroll of the collectionView    

        func scrollViewDidScroll(_ scrollView: UIScrollView) {
                if scrollView == mainScrollView {
                    if scrollView.contentOffset.y >= maxOffsetY {
                        scrollView.setContentOffset(CGPoint(x: 0, y: maxOffsetY), animated: false)
                        mainScrollView.isScrollEnabled = false
                        subScrollView.isScrollEnabled = true
                        subScrollEnabled = true
                         mainScrollEnabled = false
                    }
                }else {
                    if scrollView.contentOffset.y <= 0 {
                        scrollView.setContentOffset(CGPoint(x: 0, y: 0), animated: false)
                        subScrollView.isScrollEnabled = false
                        mainScrollView.isScrollEnabled = true
                        mainScrollEnabled = true
                        subScrollEnabled = false
                    }
                }
            }

// Then we handle the situation that the collectionView reaches the end , by the pan gesture's recognizer .    
            var currentPanY: CGFloat = 0

            func panGestureRecognizerAction(recognizer: UIPanGestureRecognizer) {
                    if recognizer.state != .changed{
                        currentPanY = 0
                        // clear the data of last time after finishing the scroll 
                        mainScrollEnabled = false
                        subScrollEnabled = false
                    }else {
                       let currentY = recognizer.translation(in: mainScrollView).y
                       // So the collectionView reaches the end.
                        if mainScrollEnabled || subScrollEnabled {
                            if currentPanY == 0 {
                                currentPanY = currentY  //get the y
                            }
                            let offsetY = currentPanY - currentY //get the offsetY

                            if mainScrollEnabled {
                               let supposeY = maxOffsetY + offsetY
                                if supposeY >= 0 {
                                    mainScrollView.contentOffset = CGPoint(x: 0, y: supposeY)
                                }else {
                                    mainScrollView.contentOffset = CGPoint.zero
                                }
                            }else {
                                subScrollView.contentOffset = CGPoint(x: 0, y: offsetY)
                            }
                        }
                    }
                }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM