'ScrollView contentOffset reset after pushViewController

I'm experiencing a problem with ScrollView, my scrollView has 640 of width, from 0 to 320 it's a mapView, from 320 to 640 it's a tableView. I have a segmentedButton with 2 options to switch my view from contentOffset from 0 to 320 in x. The problem is, if I switch to contentOffset of 320 in x and press a cell of tableView, after releasing the button to push other viewController, the contentOffset of my scrollView is reseting to 0 in x. I need to keep contentOffset on the tableView, at 320 in x. I tried many things, like playing around with viewWillDisappear and the lifecycle methods. The closest I've been able to reach was making it going back to the tableView after pressing back. Although, I couldn't make it stay on the tableView to push the next viewController.

Any help is appreciated!

(Ps: I've search for similar questions, but the only one that could help, I couldn't understand very well, the others have similar but different problems).

Thanks



Solution 1:[1]

I had the same problem. Here is the solution: 1. I'm doing content offset backup in viewWillDisappear 2. Restoring offset without animation in viewWillAppear.

UPDATE: Be sure you are not adjusting contentSize in viewWillLayoutSubviews or in methods mentioned above.

Solution 2:[2]

I have very similar problem with UItableView which is also UIScrollView, but vertical. Playing with viewWillDisappear: does not work because there is a noticeable scroll made by iOS when user initiated a push of another VC.

Can't resolve this problem as well.

Solution 3:[3]

Saving contentOffset backup at viewWillDisappear is not the correct way of handling which make you even worse to handle if you have some views which required show/hide on viewWillAppear.

The best way is saving the contentOffset at scrollViewDidScroll

  1. Declare the variable where you want to save offset
var previousOffsetY: CGFloat = 0.0
var offsetLimitation: CGFloat = 50.0 // is the limit where I want to play show/hide
  1. Inside UIScrollViewDelegate which is scrollViewDidScroll, save the offset.
extension ViewController: UIScrollViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        previousOffsetY = scrollView.contentOffset.y
        UIView.animate(withDuration: 0.5, animations: {
            if offset <= self.offsetLimitation {
                // show
            } else {
                // hide
            }
        })
    }
}
  1. At viewWillAppear, control the UI you want when offset is reseted.
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    if previousOffsetY > offsetLimitation {
        // hide
    }
}

Solution 4:[4]

check your scrollview frame when push to a new controller, if scrollview frame changed, scrollview will reset it's contentOffset

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Vlad E. Borovtsov
Solution 2 Mix
Solution 3 Thiha Aung
Solution 4 decazuk