forked from shadowfacts/Tusker
Don't use UIPageViewController for SegmentedPageViewController
This commit is contained in:
parent
baa9dfe0f1
commit
e4f3735c9f
|
@ -12,8 +12,8 @@ protocol SegmentedPageViewControllerPage: Hashable {
|
|||
var segmentedControlTitle: String { get }
|
||||
}
|
||||
|
||||
class SegmentedPageViewController<Page: SegmentedPageViewControllerPage>: UIPageViewController, UIPageViewControllerDelegate, TabbedPageViewController {
|
||||
|
||||
class SegmentedPageViewController<Page: SegmentedPageViewControllerPage>: UIViewController, UIPageViewControllerDelegate, TabbedPageViewController {
|
||||
|
||||
private(set) var pages: [Page]!
|
||||
private let pageProvider: (Page) -> UIViewController
|
||||
private var pageControllers = [Page: UIViewController]()
|
||||
|
@ -23,12 +23,10 @@ class SegmentedPageViewController<Page: SegmentedPageViewControllerPage>: UIPage
|
|||
var currentIndex: Int! {
|
||||
pages.firstIndex(of: currentPage)
|
||||
}
|
||||
var currentViewController: UIViewController! {
|
||||
viewControllers?.first
|
||||
}
|
||||
var currentViewController: UIViewController!
|
||||
|
||||
let segmentedControl = ScrollingSegmentedControl<Page>()
|
||||
|
||||
|
||||
init(pages: [Page], pageProvider: @escaping (Page) -> UIViewController) {
|
||||
precondition(!pages.isEmpty)
|
||||
|
||||
|
@ -37,7 +35,7 @@ class SegmentedPageViewController<Page: SegmentedPageViewControllerPage>: UIPage
|
|||
initialPage = pages.first!
|
||||
currentPage = pages.first!
|
||||
|
||||
super.init(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
|
||||
setPages(pages, animated: false)
|
||||
|
||||
|
@ -104,12 +102,12 @@ class SegmentedPageViewController<Page: SegmentedPageViewControllerPage>: UIPage
|
|||
initialPage = page
|
||||
return
|
||||
}
|
||||
let direction: UIPageViewController.NavigationDirection
|
||||
let direction: AnimationMode
|
||||
if let prevIndex = currentIndex {
|
||||
let index = pages.firstIndex(of: page)!
|
||||
direction = index - prevIndex > 0 ? .forward : .reverse
|
||||
} else {
|
||||
direction = .forward
|
||||
direction = .none
|
||||
}
|
||||
|
||||
currentPage = page
|
||||
|
@ -121,12 +119,40 @@ class SegmentedPageViewController<Page: SegmentedPageViewControllerPage>: UIPage
|
|||
pageControllers[page] = newController
|
||||
}
|
||||
|
||||
setViewControllers([newController], direction: direction, animated: animated)
|
||||
setViewController(newController, animated: animated ? direction : .none)
|
||||
navigationItem.title = newController.title
|
||||
|
||||
segmentedControl.setSelectedOption(page, animated: animated)
|
||||
}
|
||||
|
||||
private func setViewController(_ newViewController: UIViewController, animated: AnimationMode) {
|
||||
guard let currentViewController,
|
||||
animated != .none else {
|
||||
currentViewController?.removeViewAndController()
|
||||
newViewController.view.translatesAutoresizingMaskIntoConstraints = false
|
||||
embedChild(newViewController)
|
||||
self.currentViewController = newViewController
|
||||
return
|
||||
}
|
||||
guard currentViewController !== newViewController else {
|
||||
return
|
||||
}
|
||||
self.currentViewController = newViewController
|
||||
newViewController.view.translatesAutoresizingMaskIntoConstraints = false
|
||||
embedChild(newViewController)
|
||||
let direction: CGFloat = animated == .forward ? 1 : -1
|
||||
newViewController.view.transform = CGAffineTransform(translationX: direction * view.bounds.width, y: 0)
|
||||
let animator = UIViewPropertyAnimator(duration: 0.5, timingParameters: UISpringTimingParameters(dampingRatio: 1, initialVelocity: .zero))
|
||||
animator.addAnimations {
|
||||
newViewController.view.transform = .identity
|
||||
currentViewController.view.transform = CGAffineTransform(translationX: -1 * direction * self.view.bounds.width, y: 0)
|
||||
}
|
||||
animator.addCompletion { _ in
|
||||
currentViewController.removeViewAndController()
|
||||
}
|
||||
animator.startAnimation()
|
||||
}
|
||||
|
||||
// MARK: TabbedPageViewController
|
||||
|
||||
func selectNextPage() {
|
||||
|
@ -138,7 +164,14 @@ class SegmentedPageViewController<Page: SegmentedPageViewControllerPage>: UIPage
|
|||
guard currentIndex > 0 else { return }
|
||||
selectPage(pages[currentIndex - 1], animated: true)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension SegmentedPageViewController {
|
||||
enum AnimationMode: Equatable {
|
||||
case none
|
||||
case forward
|
||||
case reverse
|
||||
}
|
||||
}
|
||||
|
||||
extension SegmentedPageViewController: TabBarScrollableViewController {
|
||||
|
|
Loading…
Reference in New Issue