zenangst / Family

:children_crossing: A child view controller framework that makes setting up your parent controllers as easy as pie.
Other
250 stars 10 forks source link

Feature request: Allow collection view that can both scrolling vertically and horizontally #155

Closed superk589 closed 5 years ago

superk589 commented 5 years ago

I can hardly say this is a reasonable use case. But this is what I am dealing with. There is a collection view, like an excel table, which can scroll both vertically and horizontally, is inside a FamilyViewController. But with isDirectionalLockEnabled, it can only scroll at one direction at one time.

Because FamilyScrollView has code lines below:

  func configureScrollView(_ scrollView: UIScrollView) {
    #if os(iOS)
    scrollView.scrollsToTop = false
    if let collectionView = scrollView as? UICollectionView,
      (collectionView.collectionViewLayout as? UICollectionViewFlowLayout)?.scrollDirection == .horizontal {
      scrollView.isScrollEnabled = true
    } else {
      scrollView.isScrollEnabled = false
    }
    #else
    for scrollView in subviewsInLayoutOrder {
      scrollView.isScrollEnabled = scrollViewIsHorizontal(scrollView)
    }
    #endif
  }

The "excel" collection view always has it's scrollView.isScrollEnabled on. It sometimes freezes the whole FamilyViewController vertically, when it fills the whole screen and can only scroll horizontally. The gesture can not pass to the container scroll view below.

zenangst commented 5 years ago

@superk589 So what would you propose that we do here? Adding middleware where you can do your own modifications? The scrollview are only configured when the view hierarchy is modified, I'm curious to how you work around this issue right now?

superk589 commented 5 years ago

As you mentioned, maybe it is not what this framework should do. I’ll try some ideas outside the framework first.

zenangst commented 5 years ago

I think it kinda has to force the scroll views to scroll-by-proxy than to do the actual scrolling themselves. You could easily get into a situation of recursion if the scroll view starts scrolling and the parent scroll view tries to do the same. I think we would have to reconsider the layout algorithm considerably if we want to lift this "limitation".

I think the only case that we don't currently cover is the case where you have a scroll view that does scroll in multiple directions, I have yet to implement such a thing yet… hence the reason for me never considering this as a limitation and a requirement.

superk589 commented 5 years ago

Tried an idea and it works for my use case. Just subclass UICollectionView to manually disable its gesture on the vertical direction using the delegate method.

class HorizontalCollectionView: UICollectionView {

    override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        if let velocity = (gestureRecognizer as? UIPanGestureRecognizer)?.velocity(in: self) {
            return abs(velocity.x) > abs(velocity.y)
        } else {
            return true
        }
    }
}

I think scroll-by-proxy is a little complicated and hard to maintain. It's not worth to do that. Thank you for your comments. So I can come up with this idea. I think this issue can be closed.

zenangst commented 5 years ago

@superk589 It is complex I can give you that, if we can figure out a better way of doing it I'm all for implementing that :) If you have any ideas, feel free to make a PR and we can discuss the change.

superk589 commented 5 years ago

@zenangst OK, if have any further ideas or I can make a PR for this, I'll discuss with you.