Commit ce9ea5ec by Daniel Dahan

initial pass at dyanimic swiping added that works with resource bounds

parent be896548
...@@ -114,10 +114,8 @@ open class TabMenuController: UIViewController { ...@@ -114,10 +114,8 @@ open class TabMenuController: UIViewController {
/// An Array of UIViewControllers. /// An Array of UIViewControllers.
open var viewControllers: [UIViewController] { open var viewControllers: [UIViewController] {
didSet { didSet {
oldValue.forEach { oldValue.forEach { [weak self] in
$0.willMove(toParentViewController: nil) self?.removeViewController(viewController: $0)
$0.view.removeFromSuperview()
$0.removeFromParentViewController()
} }
prepareViewControllers() prepareViewControllers()
...@@ -131,6 +129,9 @@ open class TabMenuController: UIViewController { ...@@ -131,6 +129,9 @@ open class TabMenuController: UIViewController {
} }
} }
/// The number of views used in the scrollViewPool.
fileprivate let viewPoolCount = 3
/** /**
An initializer that initializes the object with a NSCoder object. An initializer that initializes the object with a NSCoder object.
- Parameter aDecoder: A NSCoder instance. - Parameter aDecoder: A NSCoder instance.
...@@ -220,48 +221,21 @@ extension TabMenuController { ...@@ -220,48 +221,21 @@ extension TabMenuController {
/// Prepares the view controllers. /// Prepares the view controllers.
fileprivate func prepareViewControllers() { fileprivate func prepareViewControllers() {
let count = 2 < viewControllers.count ? 3 : viewControllers.count let count = viewPoolCount < viewControllers.count ? viewPoolCount : viewControllers.count
scrollView.contentSize = CGSize(width: scrollView.width * CGFloat(count), height: scrollView.height) scrollView.contentSize = CGSize(width: scrollView.width * CGFloat(count), height: scrollView.height)
if 0 == selectedIndex { if 0 == selectedIndex {
for i in 0..<count { for i in 0..<count - 1 {
let vc = viewControllers[i] prepareViewController(at: i)
addChildViewController(vc)
vc.didMove(toParentViewController: self)
vc.view.clipsToBounds = true
vc.view.contentScaleFactor = Screen.scale
scrollView.addSubview(vc.view)
} }
} else if viewControllers.count - 1 == selectedIndex { } else if viewControllers.count - 1 == selectedIndex {
for i in 0..<count { for i in 0..<count - 1 {
let vc = viewControllers[count - i - 1] prepareViewController(at: count - i - 1)
addChildViewController(vc)
vc.didMove(toParentViewController: self)
vc.view.clipsToBounds = true
vc.view.contentScaleFactor = Screen.scale
scrollView.addSubview(vc.view)
} }
} else { } else {
var vc = viewControllers[selectedIndex] prepareViewController(at: selectedIndex)
addChildViewController(vc) prepareViewController(at: selectedIndex - 1)
vc.didMove(toParentViewController: self) prepareViewController(at: selectedIndex + 1)
vc.view.clipsToBounds = true
vc.view.contentScaleFactor = Screen.scale
scrollView.addSubview(vc.view)
vc = viewControllers[selectedIndex - 1]
addChildViewController(vc)
vc.didMove(toParentViewController: self)
vc.view.clipsToBounds = true
vc.view.contentScaleFactor = Screen.scale
scrollView.addSubview(vc.view)
vc = viewControllers[selectedIndex + 1]
addChildViewController(vc)
vc.didMove(toParentViewController: self)
vc.view.clipsToBounds = true
vc.view.contentScaleFactor = Screen.scale
scrollView.addSubview(vc.view)
} }
prepareTabBar() prepareTabBar()
...@@ -315,6 +289,25 @@ extension TabMenuController { ...@@ -315,6 +289,25 @@ extension TabMenuController {
view.addSubview(tabBar!) view.addSubview(tabBar!)
prepareTabBarButtons(buttons) prepareTabBarButtons(buttons)
} }
/**
Loads a view controller based on its index in the viewControllers Array
and adds it as a child view controller.
- Parameter at index: An Int for the viewControllers index.
*/
fileprivate func prepareViewController(at index: Int) {
let vc = viewControllers[index]
guard !childViewControllers.contains(vc) else {
return
}
addChildViewController(vc)
vc.didMove(toParentViewController: self)
vc.view.clipsToBounds = true
vc.view.contentScaleFactor = Screen.scale
scrollView.addSubview(vc.view)
}
} }
extension TabMenuController { extension TabMenuController {
...@@ -325,31 +318,53 @@ extension TabMenuController { ...@@ -325,31 +318,53 @@ extension TabMenuController {
} }
fileprivate func layoutViewControllers() { fileprivate func layoutViewControllers() {
let count = 2 < viewControllers.count ? 3 : viewControllers.count let count = viewPoolCount < viewControllers.count ? viewPoolCount : viewControllers.count
scrollView.contentSize = CGSize(width: scrollView.width * CGFloat(count), height: scrollView.height) scrollView.contentSize = CGSize(width: scrollView.width * CGFloat(count), height: scrollView.height)
if 0 == selectedIndex { if 0 == selectedIndex {
for i in 0..<count { for i in 0..<count {
let vc = viewControllers[i] layoutViewController(at: i, position: i)
vc.view.frame = CGRect(x: CGFloat(i) * scrollView.width, y: 0, width: scrollView.width, height: scrollView.height)
} }
} else if viewControllers.count - 1 == selectedIndex { } else if viewControllers.count - 1 == selectedIndex {
for i in 0..<count { for i in 0..<count {
let j = count - i - 1 let j = count - i - 1
let vc = viewControllers[j] layoutViewController(at: j, position: j)
vc.view.frame = CGRect(x: CGFloat(j) * scrollView.width, y: 0, width: scrollView.width, height: scrollView.height)
} }
} else { } else {
var vc = viewControllers[selectedIndex] layoutViewController(at: selectedIndex, position: 1)
vc.view.frame = CGRect(x: scrollView.width, y: 0, width: scrollView.width, height: scrollView.height) layoutViewController(at: selectedIndex - 1, position: 0)
layoutViewController(at: selectedIndex + 1, position: 2)
vc = viewControllers[selectedIndex - 1]
vc.view.frame = CGRect(x: 0, y: 0, width: scrollView.width, height: scrollView.height)
vc = viewControllers[selectedIndex + 1]
vc.view.frame = CGRect(x: 2 * scrollView.width, y: 0, width: scrollView.width, height: scrollView.height)
} }
}
/**
Positions a view controller within the scrollView.
- Parameter position: An Int for the position of the view controller.
*/
fileprivate func layoutViewController(at index: Int, position: Int) {
let vc = viewControllers[index]
vc.view.frame = CGRect(x: CGFloat(position) * scrollView.width, y: 0, width: scrollView.width, height: scrollView.height)
}
}
extension TabMenuController {
/**
Removes the view controller as a child view controller with
the given index.
- Parameter at index: An Int for the view controller position.
*/
fileprivate func removeViewController(at index: Int) {
removeViewController(viewController: viewControllers[index])
}
/**
Removes a given view controller from the childViewControllers array.
- Parameter at index: An Int for the view controller position.
*/
fileprivate func removeViewController(viewController: UIViewController) {
viewController.willMove(toParentViewController: nil)
viewController.view.removeFromSuperview()
viewController.removeFromParentViewController()
} }
} }
...@@ -388,6 +403,8 @@ extension TabMenuController { ...@@ -388,6 +403,8 @@ extension TabMenuController {
} }
selectedIndex = index selectedIndex = index
prepareViewControllers()
layoutViewControllers()
} }
} }
...@@ -413,5 +430,7 @@ extension TabMenuController: UIScrollViewDelegate { ...@@ -413,5 +430,7 @@ extension TabMenuController: UIScrollViewDelegate {
@objc @objc
open func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { open func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
selectedIndex = lround(Double(scrollView.contentOffset.x / scrollView.width)) selectedIndex = lround(Double(scrollView.contentOffset.x / scrollView.width))
prepareViewControllers()
layoutViewControllers()
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment