From 85b437ab164d361d3c5ee4357d31f4968a28c8d6 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Wed, 1 Jan 2020 11:34:58 -0500 Subject: [PATCH] Allow multiple scroll views inside a navigation controller --- .../SheetContainerViewController.swift | 32 +++++++++++++++---- .../ContentTableViewController.swift | 3 ++ SheetImagePickerTest/ViewController.swift | 17 +++++++--- 3 files changed, 41 insertions(+), 11 deletions(-) diff --git a/SheetImagePicker/SheetContainerViewController.swift b/SheetImagePicker/SheetContainerViewController.swift index 99f0669..1339b0a 100644 --- a/SheetImagePicker/SheetContainerViewController.swift +++ b/SheetImagePicker/SheetContainerViewController.swift @@ -56,6 +56,8 @@ public class SheetContainerViewController: UIViewController { var contentScrollView: UIScrollView? { delegate?.sheetContainerContentScrollView(self) ?? content.view as? UIScrollView } + var initialScrollViewContentOffset: CGPoint? + var scrollViewIsMovingSheet = false public init(content: UIViewController) { self.content = content @@ -100,6 +102,10 @@ public class SheetContainerViewController: UIViewController { panGesture.delegate = self content.view.addGestureRecognizer(panGesture) + contentScrollViewChanged() + } + + public func contentScrollViewChanged() { if let scrollView = contentScrollView { scrollView.panGestureRecognizer.addTarget(self, action: #selector(scrollViewPanGestureRecognized)) } @@ -134,14 +140,23 @@ public class SheetContainerViewController: UIViewController { let shouldMoveSheetUp = topConstraint.constant > topDetent.offset && velocity.y < 0 // not fully expanded and dragging up let shouldMoveSheet = shouldMoveSheetDown || shouldMoveSheetUp - if shouldMoveSheet { - scrollView.bounces = false - scrollView.setContentOffset(CGPoint(x: 0, y: topContentOffset), animated: false) - } switch recognizer.state { - case .changed: + case .began: + scrollView.bounces = false + scrollViewIsMovingSheet = shouldMoveSheet if shouldMoveSheet { + initialScrollViewContentOffset = scrollView.contentOffset + } + + case .changed: + scrollViewIsMovingSheet = scrollViewIsMovingSheet || shouldMoveSheet + if scrollViewIsMovingSheet { + if initialScrollViewContentOffset == nil { + initialScrollViewContentOffset = scrollView.contentOffset + } + scrollView.setContentOffset(initialScrollViewContentOffset!, animated: false) + let translation = recognizer.translation(in: scrollView) setTopOffset(topConstraint.constant + translation.y) recognizer.setTranslation(.zero, in: scrollView) @@ -149,9 +164,12 @@ public class SheetContainerViewController: UIViewController { case .ended: scrollView.bounces = true - if shouldMoveSheet { + if scrollViewIsMovingSheet { + scrollView.setContentOffset(initialScrollViewContentOffset!, animated: false) springToNearestDetent(verticalVelocity: velocity.y) } + scrollViewIsMovingSheet = false + initialScrollViewContentOffset = nil default: break @@ -165,8 +183,8 @@ public class SheetContainerViewController: UIViewController { if offset < topOffset { let smoothed = smoothstep(value: offset, from: topOffset, to: 0) offset = topOffset - smoothed * maximumStretchDistance - } + topConstraint.constant = offset dimmingView.alpha = lerp(offset, min: topOffset, max: bottomDetent.offset, from: maximumDimmingAlpha, to: minimumDimmingAlpha) } diff --git a/SheetImagePickerTest/ContentTableViewController.swift b/SheetImagePickerTest/ContentTableViewController.swift index 75a5654..9f97ca7 100644 --- a/SheetImagePickerTest/ContentTableViewController.swift +++ b/SheetImagePickerTest/ContentTableViewController.swift @@ -44,6 +44,9 @@ class ContentTableViewController: UITableViewController { override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { guard let navController = navigationController else { return } + navController.pushViewController(ContentTableViewController(), animated: true) + return + let vc = UIViewController() vc.view.backgroundColor = .systemBackground let label = UILabel() diff --git a/SheetImagePickerTest/ViewController.swift b/SheetImagePickerTest/ViewController.swift index 5adba45..80c7d70 100644 --- a/SheetImagePickerTest/ViewController.swift +++ b/SheetImagePickerTest/ViewController.swift @@ -10,6 +10,8 @@ import UIKit import SheetImagePicker class ViewController: UIViewController { + + var sheet: SheetContainerViewController! override func viewDidLoad() { super.viewDidLoad() @@ -37,7 +39,7 @@ class ViewController: UIViewController { label.centerYAnchor.constraint(equalTo: blurView.contentView.centerYAnchor) ]) - let sheet = SheetContainerViewController(content: content) + sheet = SheetContainerViewController(content: content) sheet.delegate = self sheet.detents = [.bottom, .middle, .top] @@ -50,7 +52,7 @@ class ViewController: UIViewController { content.view.layer.masksToBounds = true content.view.layer.cornerRadius = view.bounds.width * 0.02 - let sheet = SheetContainerViewController(content: content) + sheet = SheetContainerViewController(content: content) sheet.delegate = self sheet.detents = [.bottom, .middle, .top] @@ -74,7 +76,7 @@ class ViewController: UIViewController { nav.view.layer.masksToBounds = true nav.view.layer.cornerRadius = view.bounds.width * 0.02 - let sheet = SheetContainerViewController(content: nav) + sheet = SheetContainerViewController(content: nav) sheet.delegate = self sheet.detents = [.bottom, .middle, .top] @@ -85,11 +87,12 @@ class ViewController: UIViewController { let table = ContentTableViewController() let nav = UINavigationController(rootViewController: table) + nav.delegate = self nav.view.translatesAutoresizingMaskIntoConstraints = false nav.view.layer.masksToBounds = true nav.view.layer.cornerRadius = view.bounds.width * 0.02 - let sheet = SheetContainerViewController(content: nav) + sheet = SheetContainerViewController(content: nav) sheet.delegate = self sheet.detents = [.bottom, .middle, .top] @@ -120,3 +123,9 @@ extension ViewController: SheetContainerViewControllerDelegate { } } } + +extension ViewController: UINavigationControllerDelegate { + func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) { + sheet.contentScrollViewChanged() + } +}