Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixed "Odd scroll jumping when navigating from profile #16" #17

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions TwitterProfile/Classes/Protocols/BottomPageDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ import UIKit

public protocol BottomPageDelegate: class {
func tp_pageViewController(_ currentViewController: UIViewController?, didSelectPageAt index: Int)
func tp_pageViewController(_ currentViewController: UIViewController?, didBeforeSelectPageAt index: Int)
}
2 changes: 2 additions & 0 deletions TwitterProfile/Classes/Protocols/TPDataSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@ public protocol TPDataSource: class {
func headerViewController() -> UIViewController
func bottomViewController() -> UIViewController & PagerAwareProtocol
func minHeaderHeight() -> CGFloat //stop scrolling headerView at this point
func resetOffsetViewWillAppear() -> Bool
func resetOffsetViewDidAppear() -> Bool
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,23 @@

import UIKit

class ContainerViewController : UIViewController, UIScrollViewDelegate {
class ContainerViewController : UIViewController, UIScrollViewDelegate, UINavigationControllerDelegate {

func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
let contentOffsetY = subContentOffsets[currentIndex] ?? 0
(self.panViews[currentIndex] as? UIScrollView)?.contentOffset.y = contentOffsetY
}

func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
let contentOffsetY = subContentOffsets[currentIndex] ?? 0
(self.panViews[currentIndex] as? UIScrollView)?.contentOffset.y = contentOffsetY
}

private var containerScrollView: UIScrollView! //contains headerVC + bottomVC
private var overlayScrollView: UIScrollView! //handles whole scroll logic
private var panViews: [Int: UIView] = [:] {// bottom view(s)/scrollView(s)
didSet{
if let scrollView = panViews[currentIndex] as? UIScrollView{
if let scrollView = panViews[currentIndex] as? UIScrollView {
scrollView.panGestureRecognizer.require(toFail: overlayScrollView.panGestureRecognizer)
scrollView.donotAdjustContentInset()
scrollView.addObserver(self, forKeyPath: #keyPath(UIScrollView.contentSize), options: .new, context: nil)
Expand Down Expand Up @@ -42,7 +53,8 @@ class ContainerViewController : UIViewController, UIScrollViewDelegate {
private var bottomVC: (UIViewController & PagerAwareProtocol)!

private var contentOffsets: [Int: CGFloat] = [:]

private var subContentOffsets: [Int: CGFloat] = [:]


deinit {
self.panViews.forEach({ (arg0) in
Expand Down Expand Up @@ -74,7 +86,7 @@ class ContainerViewController : UIViewController, UIScrollViewDelegate {

override func viewDidLoad() {
super.viewDidLoad()

navigationController?.delegate = self
///Configure overlay scroll
overlayScrollView.delegate = self
overlayScrollView.layer.zPosition = CGFloat.greatestFiniteMagnitude
Expand Down Expand Up @@ -114,6 +126,28 @@ class ContainerViewController : UIViewController, UIScrollViewDelegate {
delegate?.tp_scrollViewDidLoad(overlayScrollView)
}

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)

if self.dataSource.resetOffsetViewWillAppear() && self.overlayScrollView != nil {
self.scrollViewDidScroll(self.overlayScrollView)
}
}

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if self.dataSource.resetOffsetViewDidAppear() && self.overlayScrollView != nil {
self.scrollViewDidScroll(self.overlayScrollView)
}
}

override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
let contentOffsetY = subContentOffsets[currentIndex] ?? 0
(self.panViews[currentIndex] as? UIScrollView)?.contentOffset.y = contentOffsetY
print("viewDidDisappear", contentOffsetY)
}

private func updateOverlayScrollContentSize(with bottomView: UIView){
self.overlayScrollView.contentSize = getContentSize(for: bottomView)
}
Expand All @@ -138,26 +172,33 @@ class ContainerViewController : UIViewController, UIScrollViewDelegate {
}
}
}

func scrollViewDidScroll(_ scrollView: UIScrollView) {
contentOffsets[currentIndex] = scrollView.contentOffset.y
let topHeight = bottomView.frame.minY - dataSource.minHeaderHeight()

if scrollView.contentOffset.y < topHeight{
let topHeight = bottomView.frame.minY - dataSource.minHeaderHeight() - 1
if scrollView.contentOffset.y < topHeight {
self.containerScrollView.contentOffset.y = scrollView.contentOffset.y
self.panViews.forEach({ (arg0) in
let (_, value) = arg0
(value as? UIScrollView)?.contentOffset.y = 0
})
contentOffsets.removeAll()
}else{
self.containerScrollView.contentOffset.y = topHeight
(self.panViews[currentIndex] as? UIScrollView)?.contentOffset.y = scrollView.contentOffset.y - self.containerScrollView.contentOffset.y

let progress = self.containerScrollView.contentOffset.y / topHeight
if progress < 0.99 {
contentOffsets.removeAll()
subContentOffsets.removeAll()
}
self.delegate?.tp_scrollView(self.containerScrollView, didUpdate: progress)
} else {
self.containerScrollView.contentOffset.y = topHeight
let contentOffsetY = scrollView.contentOffset.y - self.containerScrollView.contentOffset.y
(self.panViews[currentIndex] as? UIScrollView)?.contentOffset.y = contentOffsetY
self.subContentOffsets[currentIndex] = contentOffsetY
let progress = self.containerScrollView.contentOffset.y / topHeight
self.delegate?.tp_scrollView(self.containerScrollView, didUpdate: progress)
}

let progress = self.containerScrollView.contentOffset.y / topHeight
self.delegate?.tp_scrollView(self.containerScrollView, didUpdate: progress)

}
}

Expand All @@ -167,7 +208,7 @@ extension ContainerViewController : BottomPageDelegate {
func tp_pageViewController(_ currentViewController: UIViewController?, didSelectPageAt index: Int) {
currentIndex = index

if let offset = contentOffsets[index]{
if let offset = contentOffsets[index] {
self.overlayScrollView.contentOffset.y = offset
}else{
self.overlayScrollView.contentOffset.y = self.containerScrollView.contentOffset.y
Expand All @@ -178,9 +219,18 @@ extension ContainerViewController : BottomPageDelegate {
}


if let panView = self.panViews[currentIndex]{
if let panView = self.panViews[currentIndex] {
updateOverlayScrollContentSize(with: panView)
}

for (index, offset) in self.subContentOffsets {
(self.panViews[index] as? UIScrollView)?.contentOffset.y = offset
}

}

func tp_pageViewController(_ currentViewController: UIViewController?, didBeforeSelectPageAt index: Int) {
let contentOffsetY = subContentOffsets[index] ?? 0
(self.panViews[index] as? UIScrollView)?.contentOffset.y = contentOffsetY
}

}