Allow multiple scroll views inside a navigation controller
This commit is contained in:
parent
f79d5a6b59
commit
85b437ab16
|
@ -56,6 +56,8 @@ public class SheetContainerViewController: UIViewController {
|
||||||
var contentScrollView: UIScrollView? {
|
var contentScrollView: UIScrollView? {
|
||||||
delegate?.sheetContainerContentScrollView(self) ?? content.view as? UIScrollView
|
delegate?.sheetContainerContentScrollView(self) ?? content.view as? UIScrollView
|
||||||
}
|
}
|
||||||
|
var initialScrollViewContentOffset: CGPoint?
|
||||||
|
var scrollViewIsMovingSheet = false
|
||||||
|
|
||||||
public init(content: UIViewController) {
|
public init(content: UIViewController) {
|
||||||
self.content = content
|
self.content = content
|
||||||
|
@ -100,6 +102,10 @@ public class SheetContainerViewController: UIViewController {
|
||||||
panGesture.delegate = self
|
panGesture.delegate = self
|
||||||
content.view.addGestureRecognizer(panGesture)
|
content.view.addGestureRecognizer(panGesture)
|
||||||
|
|
||||||
|
contentScrollViewChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
public func contentScrollViewChanged() {
|
||||||
if let scrollView = contentScrollView {
|
if let scrollView = contentScrollView {
|
||||||
scrollView.panGestureRecognizer.addTarget(self, action: #selector(scrollViewPanGestureRecognized))
|
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 shouldMoveSheetUp = topConstraint.constant > topDetent.offset && velocity.y < 0 // not fully expanded and dragging up
|
||||||
|
|
||||||
let shouldMoveSheet = shouldMoveSheetDown || shouldMoveSheetUp
|
let shouldMoveSheet = shouldMoveSheetDown || shouldMoveSheetUp
|
||||||
if shouldMoveSheet {
|
|
||||||
scrollView.bounces = false
|
|
||||||
scrollView.setContentOffset(CGPoint(x: 0, y: topContentOffset), animated: false)
|
|
||||||
}
|
|
||||||
|
|
||||||
switch recognizer.state {
|
switch recognizer.state {
|
||||||
case .changed:
|
case .began:
|
||||||
|
scrollView.bounces = false
|
||||||
|
scrollViewIsMovingSheet = shouldMoveSheet
|
||||||
if 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)
|
let translation = recognizer.translation(in: scrollView)
|
||||||
setTopOffset(topConstraint.constant + translation.y)
|
setTopOffset(topConstraint.constant + translation.y)
|
||||||
recognizer.setTranslation(.zero, in: scrollView)
|
recognizer.setTranslation(.zero, in: scrollView)
|
||||||
|
@ -149,9 +164,12 @@ public class SheetContainerViewController: UIViewController {
|
||||||
|
|
||||||
case .ended:
|
case .ended:
|
||||||
scrollView.bounces = true
|
scrollView.bounces = true
|
||||||
if shouldMoveSheet {
|
if scrollViewIsMovingSheet {
|
||||||
|
scrollView.setContentOffset(initialScrollViewContentOffset!, animated: false)
|
||||||
springToNearestDetent(verticalVelocity: velocity.y)
|
springToNearestDetent(verticalVelocity: velocity.y)
|
||||||
}
|
}
|
||||||
|
scrollViewIsMovingSheet = false
|
||||||
|
initialScrollViewContentOffset = nil
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
|
@ -165,8 +183,8 @@ public class SheetContainerViewController: UIViewController {
|
||||||
if offset < topOffset {
|
if offset < topOffset {
|
||||||
let smoothed = smoothstep(value: offset, from: topOffset, to: 0)
|
let smoothed = smoothstep(value: offset, from: topOffset, to: 0)
|
||||||
offset = topOffset - smoothed * maximumStretchDistance
|
offset = topOffset - smoothed * maximumStretchDistance
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
topConstraint.constant = offset
|
topConstraint.constant = offset
|
||||||
dimmingView.alpha = lerp(offset, min: topOffset, max: bottomDetent.offset, from: maximumDimmingAlpha, to: minimumDimmingAlpha)
|
dimmingView.alpha = lerp(offset, min: topOffset, max: bottomDetent.offset, from: maximumDimmingAlpha, to: minimumDimmingAlpha)
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,9 @@ class ContentTableViewController: UITableViewController {
|
||||||
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||||
guard let navController = navigationController else { return }
|
guard let navController = navigationController else { return }
|
||||||
|
|
||||||
|
navController.pushViewController(ContentTableViewController(), animated: true)
|
||||||
|
return
|
||||||
|
|
||||||
let vc = UIViewController()
|
let vc = UIViewController()
|
||||||
vc.view.backgroundColor = .systemBackground
|
vc.view.backgroundColor = .systemBackground
|
||||||
let label = UILabel()
|
let label = UILabel()
|
||||||
|
|
|
@ -10,6 +10,8 @@ import UIKit
|
||||||
import SheetImagePicker
|
import SheetImagePicker
|
||||||
|
|
||||||
class ViewController: UIViewController {
|
class ViewController: UIViewController {
|
||||||
|
|
||||||
|
var sheet: SheetContainerViewController!
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
|
@ -37,7 +39,7 @@ class ViewController: UIViewController {
|
||||||
label.centerYAnchor.constraint(equalTo: blurView.contentView.centerYAnchor)
|
label.centerYAnchor.constraint(equalTo: blurView.contentView.centerYAnchor)
|
||||||
])
|
])
|
||||||
|
|
||||||
let sheet = SheetContainerViewController(content: content)
|
sheet = SheetContainerViewController(content: content)
|
||||||
sheet.delegate = self
|
sheet.delegate = self
|
||||||
sheet.detents = [.bottom, .middle, .top]
|
sheet.detents = [.bottom, .middle, .top]
|
||||||
|
|
||||||
|
@ -50,7 +52,7 @@ class ViewController: UIViewController {
|
||||||
content.view.layer.masksToBounds = true
|
content.view.layer.masksToBounds = true
|
||||||
content.view.layer.cornerRadius = view.bounds.width * 0.02
|
content.view.layer.cornerRadius = view.bounds.width * 0.02
|
||||||
|
|
||||||
let sheet = SheetContainerViewController(content: content)
|
sheet = SheetContainerViewController(content: content)
|
||||||
sheet.delegate = self
|
sheet.delegate = self
|
||||||
sheet.detents = [.bottom, .middle, .top]
|
sheet.detents = [.bottom, .middle, .top]
|
||||||
|
|
||||||
|
@ -74,7 +76,7 @@ class ViewController: UIViewController {
|
||||||
nav.view.layer.masksToBounds = true
|
nav.view.layer.masksToBounds = true
|
||||||
nav.view.layer.cornerRadius = view.bounds.width * 0.02
|
nav.view.layer.cornerRadius = view.bounds.width * 0.02
|
||||||
|
|
||||||
let sheet = SheetContainerViewController(content: nav)
|
sheet = SheetContainerViewController(content: nav)
|
||||||
sheet.delegate = self
|
sheet.delegate = self
|
||||||
sheet.detents = [.bottom, .middle, .top]
|
sheet.detents = [.bottom, .middle, .top]
|
||||||
|
|
||||||
|
@ -85,11 +87,12 @@ class ViewController: UIViewController {
|
||||||
let table = ContentTableViewController()
|
let table = ContentTableViewController()
|
||||||
|
|
||||||
let nav = UINavigationController(rootViewController: table)
|
let nav = UINavigationController(rootViewController: table)
|
||||||
|
nav.delegate = self
|
||||||
nav.view.translatesAutoresizingMaskIntoConstraints = false
|
nav.view.translatesAutoresizingMaskIntoConstraints = false
|
||||||
nav.view.layer.masksToBounds = true
|
nav.view.layer.masksToBounds = true
|
||||||
nav.view.layer.cornerRadius = view.bounds.width * 0.02
|
nav.view.layer.cornerRadius = view.bounds.width * 0.02
|
||||||
|
|
||||||
let sheet = SheetContainerViewController(content: nav)
|
sheet = SheetContainerViewController(content: nav)
|
||||||
sheet.delegate = self
|
sheet.delegate = self
|
||||||
sheet.detents = [.bottom, .middle, .top]
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue