4

As you can see below I have a ViewController(lets call it viewController A) that contains a container view with a ViewController inside(lets call that ViewController B).

So whats happening below is when you scroll up ViewController A's scrollview is being used until the tabview hits the top. Once the tabview hits the top the scrollview for ViewController B takes over and starts scrolling through the container View. And when you scroll back down viewController B's scrollview goes until the top is visible and then viewController A's scrollview takes over to pull the header view back down.

The Problem

So the scrolling functionality works exactly how I want it to however my problem is when the scrollViews switch between each other it is not smooth. The user has to lift their finger of the screen and put it back down before the right scrollview is recognised. How can I make it so when a user swipes up or down the scrollviews switch smoothly between each other and not have to stop? Like an automatically transition.

I've looked at other posts but I haven't managed to anything that helps so any help would be much appreciated. Thanks in advance

enter image description here enter image description here enter image description here

ViewController A

import Foundation
import UIKit
import XLPagerTabStrip

class viewControllerA: ButtonBarPagerTabStripViewController {

      @IBOutlet weak var containerHeightConstraint: NSLayoutConstraint!
      @IBOutlet weak var scrollView: UIScrollView! 
      @IBOutlet weak var contentView: UIView!
      @IBOutlet weak var headerView: HeaderView!
      @IBOutlet weak var tabView: ButtonBarView!    
      @IBOutlet weak var viewContainer: UIScrollView!

        override func viewDidLoad() {

       self.scrollView.delegate = self

           NotificationCenter.default.addObserver(self, selector: #selector(EnableScroll), name: NSNotification.Name(rawValue: "enableScroll"), object: nil)

            containerView.isScrollEnabled = false
            self.containerView.bounces = false

            super.viewDidLoad()
        }

    @objc func EnableScroll() {
        self.scrollView.isScrollEnabled = true
    }

        override func scrollViewDidScroll(_ scrollView: UIScrollView) {
        let yOffset = scrollView.contentOffset.y
        if scrollView == self.scrollView {
            if yOffset >= 250 {
                //tabView has reached the top
                //enable ViewController B's scrollViews
                 NotificationCenter.default.post(name: NSNotification.Name(rawValue: "EnableScroll"), object: nil)
            }
        }
    }
}

ViewController B

class viewControllerB: UIViewController, IndicatorInfoProvider, UIScrollViewDelegate {

    @IBOutlet weak var scrollView: UIScrollView!

     override func viewDidLoad() {
       super.viewDidLoad(

   self.scrollView.delegate = self

  NotificationCenter.default.addObserver(self, selector: #selector(EnableScroll), name: NSNotification.Name(rawValue: "EnableScroll"), object: nil)
        }

     @objc func EnableScroll() {        
        self.scrollView.isScrollEnabled = true       
            }

      Override func scrollViewDidScroll(_ scrollView: UIScrollView) {

        let yOffset = scrollView.contentOffset.y
        if scrollView == self.scrollView {
            if yOffset <= 0 {
                //scrolling down, top of ViewControllerB is full in view
                self.scrollView.isScrollEnabled = false
                //enables ViewController A's scrollview
                 NotificationCenter.default.post(name: NSNotification.Name(rawValue: "enableScroll"), object: nil)

            }
        }
    }
}
j.iese
  • 171
  • 2
  • 12
  • You can achieve the same effect with just one controller and a `UITableView` using `tableHeaderView` for your header view, and a section header view for your tab view. Do you have a strict requirement to split the implementation into two controllers? – Callam Oct 05 '18 at 13:07
  • The tabView actually has 3 tabs which show 3 different view controllers but for the sake of the question I've made it look like one to make things simple. So to answer your question I do need to split the implementation to 2 view controllers. I tried using a protocol delegate from vcB to vcA so I could implement scrollViewDidScroll in just vcA but I wasn't able to achieve properly. Do you have any other suggestions? – j.iese Oct 05 '18 at 13:49
  • I find this solution to be very helpful: https://stackoverflow.com/a/13222086/774798 – plam4u Dec 22 '18 at 02:29
  • Hi @j.iese, I know this is an old post but did you find a solution for this? – iqra Dec 25 '21 at 12:12

0 Answers0