Commit bf177342 by Daniel Dahan

development: updated PageController to PageTabBarController and updated transition animations

parent 821a17ac
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
96334EF61C8B84660083986B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 96334EF51C8B84660083986B /* Assets.xcassets */; }; 96334EF61C8B84660083986B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 96334EF51C8B84660083986B /* Assets.xcassets */; };
963832421B88DFD80015F710 /* Material.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 963832361B88DFD80015F710 /* Material.framework */; }; 963832421B88DFD80015F710 /* Material.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 963832361B88DFD80015F710 /* Material.framework */; };
963FBEFD1D669510008F8512 /* Snackbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 963FBEFC1D669510008F8512 /* Snackbar.swift */; }; 963FBEFD1D669510008F8512 /* Snackbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 963FBEFC1D669510008F8512 /* Snackbar.swift */; };
963FBF081D669D14008F8512 /* PageController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 963FBF071D669D14008F8512 /* PageController.swift */; }; 963FBF081D669D14008F8512 /* PageTabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 963FBF071D669D14008F8512 /* PageTabBarController.swift */; };
9658F2171CD6FA4700B902C1 /* IconButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9658F2161CD6FA4700B902C1 /* IconButton.swift */; }; 9658F2171CD6FA4700B902C1 /* IconButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9658F2161CD6FA4700B902C1 /* IconButton.swift */; };
9660161D1CB2ED6C00AAB661 /* Material.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 966016131CB2ED6C00AAB661 /* Material.framework */; }; 9660161D1CB2ED6C00AAB661 /* Material.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 966016131CB2ED6C00AAB661 /* Material.framework */; };
9660162A1CB2F04E00AAB661 /* Material.h in Headers */ = {isa = PBXBuildFile; fileRef = 96D88C091C1328D800B91418 /* Material.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9660162A1CB2F04E00AAB661 /* Material.h in Headers */ = {isa = PBXBuildFile; fileRef = 96D88C091C1328D800B91418 /* Material.h */; settings = {ATTRIBUTES = (Public, ); }; };
...@@ -209,7 +209,7 @@ ...@@ -209,7 +209,7 @@
963832411B88DFD80015F710 /* Material.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Material.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 963832411B88DFD80015F710 /* Material.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Material.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
963832591B88E31A0015F710 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 963832591B88E31A0015F710 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
963FBEFC1D669510008F8512 /* Snackbar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Snackbar.swift; sourceTree = "<group>"; }; 963FBEFC1D669510008F8512 /* Snackbar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Snackbar.swift; sourceTree = "<group>"; };
963FBF071D669D14008F8512 /* PageController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PageController.swift; sourceTree = "<group>"; }; 963FBF071D669D14008F8512 /* PageTabBarController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PageTabBarController.swift; sourceTree = "<group>"; };
9658F2161CD6FA4700B902C1 /* IconButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IconButton.swift; sourceTree = "<group>"; }; 9658F2161CD6FA4700B902C1 /* IconButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IconButton.swift; sourceTree = "<group>"; };
966016131CB2ED6C00AAB661 /* Material.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Material.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 966016131CB2ED6C00AAB661 /* Material.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Material.framework; sourceTree = BUILT_PRODUCTS_DIR; };
9660161C1CB2ED6C00AAB661 /* Material macOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Material macOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 9660161C1CB2ED6C00AAB661 /* Material macOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Material macOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
...@@ -360,7 +360,7 @@ ...@@ -360,7 +360,7 @@
962DDD071D6FBBB7001C307C /* Page */ = { 962DDD071D6FBBB7001C307C /* Page */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
963FBF071D669D14008F8512 /* PageController.swift */, 963FBF071D669D14008F8512 /* PageTabBarController.swift */,
); );
name = Page; name = Page;
sourceTree = "<group>"; sourceTree = "<group>";
...@@ -1073,7 +1073,7 @@ ...@@ -1073,7 +1073,7 @@
962864621D54111D00690B69 /* JSON.swift in Sources */, 962864621D54111D00690B69 /* JSON.swift in Sources */,
96BCB7C21CB40DC500C806FE /* Device.swift in Sources */, 96BCB7C21CB40DC500C806FE /* Device.swift in Sources */,
96BCB7A41CB40DC500C806FE /* CaptureSession.swift in Sources */, 96BCB7A41CB40DC500C806FE /* CaptureSession.swift in Sources */,
963FBF081D669D14008F8512 /* PageController.swift in Sources */, 963FBF081D669D14008F8512 /* PageTabBarController.swift in Sources */,
963FBEFD1D669510008F8512 /* Snackbar.swift in Sources */, 963FBEFD1D669510008F8512 /* Snackbar.swift in Sources */,
96BCB7C51CB40DC500C806FE /* MaterialGravity.swift in Sources */, 96BCB7C51CB40DC500C806FE /* MaterialGravity.swift in Sources */,
968C99471D377849000074FF /* Offset.swift in Sources */, 968C99471D377849000074FF /* Offset.swift in Sources */,
......
...@@ -34,12 +34,19 @@ import UIKit ...@@ -34,12 +34,19 @@ import UIKit
private var PageTabBarItemKey: UInt8 = 0 private var PageTabBarItemKey: UInt8 = 0
open class PageTabBarItem: FlatButton { open class PageTabBarItem: FlatButton {
override open func prepareView() { open override func prepareView() {
super.prepareView() super.prepareView()
pulseAnimation = .none pulseAnimation = .none
} }
} }
open class PageTabBar: TabBar {
open override func prepareView() {
super.prepareView()
isLineAnimated = false
}
}
/// Grid extension for UIView. /// Grid extension for UIView.
extension UIViewController { extension UIViewController {
/// Grid reference. /// Grid reference.
...@@ -57,15 +64,15 @@ extension UIViewController { ...@@ -57,15 +64,15 @@ extension UIViewController {
extension UIViewController { extension UIViewController {
/** /**
A convenience property that provides access to the PageController. A convenience property that provides access to the PageTabBarController.
This is the recommended method of accessing the PageController This is the recommended method of accessing the PageTabBarController
through child UIViewControllers. through child UIViewControllers.
*/ */
public var pageController: PageController? { public var pageTabBarController: PageTabBarController? {
var viewController: UIViewController? = self var viewController: UIViewController? = self
while nil != viewController { while nil != viewController {
if viewController is PageController { if viewController is PageTabBarController {
return viewController as? PageController return viewController as? PageTabBarController
} }
viewController = viewController?.parent viewController = viewController?.parent
} }
...@@ -73,21 +80,21 @@ extension UIViewController { ...@@ -73,21 +80,21 @@ extension UIViewController {
} }
} }
@objc(PageControllerDelegate) @objc(PageTabBarControllerDelegate)
public protocol PageControllerDelegate { public protocol PageTabBarControllerDelegate {
} }
@objc(PageController) @objc(PageTabBarController)
open class PageController: RootController { open class PageTabBarController: RootController {
/// The currently selected UIViewController. /// The currently selected UIViewController.
open internal(set) var selectedIndex: Int = 0 open internal(set) var selectedIndex: Int = 0
/// Reference to the TabBar. /// Reference to the PageTabBar.
open internal(set) var tabBar: TabBar! open internal(set) var pageTabBar: PageTabBar!
/// Delegation handler. /// Delegation handler.
public weak var delegate: PageControllerDelegate? public weak var delegate: PageTabBarControllerDelegate?
/// A reference to the instance when it is a UIPageViewController. /// A reference to the instance when it is a UIPageViewController.
open var pageViewController: UIPageViewController? { open var pageViewController: UIPageViewController? {
...@@ -104,14 +111,14 @@ open class PageController: RootController { ...@@ -104,14 +111,14 @@ open class PageController: RootController {
public override init(rootViewController: UIViewController) { public override init(rootViewController: UIViewController) {
super.init(rootViewController: UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)) super.init(rootViewController: UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil))
viewControllers.append(rootViewController) viewControllers.append(rootViewController)
setViewControllers(viewControllers, direction: .forward, animated: true, completion: nil) setViewControllers(viewControllers, direction: .forward, animated: true)
} }
public init(viewControllers: [UIViewController], selectedIndex: Int, direction: UIPageViewControllerNavigationDirection, animated: Bool) { public init(viewControllers: [UIViewController], selectedIndex: Int, direction: UIPageViewControllerNavigationDirection, animated: Bool) {
super.init(rootViewController: UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)) super.init(rootViewController: UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil))
self.selectedIndex = selectedIndex self.selectedIndex = selectedIndex
self.viewControllers.append(contentsOf: viewControllers) self.viewControllers.append(contentsOf: viewControllers)
setViewControllers([self.viewControllers[selectedIndex]], direction: direction, animated: animated, completion: nil) setViewControllers([self.viewControllers[selectedIndex]], direction: direction, animated: animated)
} }
/** /**
...@@ -121,7 +128,7 @@ open class PageController: RootController { ...@@ -121,7 +128,7 @@ open class PageController: RootController {
*/ */
open override func layoutSubviews() { open override func layoutSubviews() {
super.layoutSubviews() super.layoutSubviews()
guard let v = tabBar else { guard let v = pageTabBar else {
return return
} }
...@@ -149,7 +156,7 @@ open class PageController: RootController { ...@@ -149,7 +156,7 @@ open class PageController: RootController {
*/ */
open override func prepareView() { open override func prepareView() {
super.prepareView() super.prepareView()
prepareTabBar() preparePageTabBar()
} }
override func prepareRootViewController() { override func prepareRootViewController() {
...@@ -172,31 +179,59 @@ open class PageController: RootController { ...@@ -172,31 +179,59 @@ open class PageController: RootController {
/// Prepares the pageTabBarItems. /// Prepares the pageTabBarItems.
open func preparePageTabBarItems() { open func preparePageTabBarItems() {
tabBar.buttons.removeAll() pageTabBar.buttons.removeAll()
for x in viewControllers { for x in viewControllers {
tabBar.buttons.append(x.pageTabBarItem as UIButton) let button = x.pageTabBarItem as UIButton
pageTabBar.buttons.append(button)
button.removeTarget(self, action: #selector(pageTabBar.handleButton(button:)), for: .touchUpInside)
button.removeTarget(self, action: #selector(handlePageTabBarButton(button:)), for: .touchUpInside)
button.addTarget(self, action: #selector(handlePageTabBarButton(button:)), for: .touchUpInside)
} }
} }
/// Prepares the tabBar. /**
private func prepareTabBar() { Handles the pageTabBarButton.
if nil == tabBar { - Parameter button: A UIButton.
tabBar = TabBar() */
tabBar.zPosition = 1000 @objc
view.addSubview(tabBar) internal func handlePageTabBarButton(button: UIButton) {
tabBar.select(at: selectedIndex) guard let index = pageTabBar.buttons.index(of: button) else {
return
}
guard index != selectedIndex else {
return
}
setViewControllers([viewControllers[index]], direction: index < selectedIndex ? .reverse : .forward, animated: true) { [weak self, index = index] _ in
guard let s = self else {
return
}
s.selectedIndex = index
s.pageTabBar.select(at: index)
}
}
/// Prepares the pageTabBar.
private func preparePageTabBar() {
if nil == pageTabBar {
pageTabBar = PageTabBar()
pageTabBar.zPosition = 1000
view.addSubview(pageTabBar)
pageTabBar.select(at: selectedIndex)
} }
} }
} }
extension PageController { extension PageTabBarController {
open func setViewControllers(_ viewControllers: [UIViewController]?, direction: UIPageViewControllerNavigationDirection, animated: Bool, completion: (@escaping (Bool) -> Void)? = nil) { open func setViewControllers(_ viewControllers: [UIViewController]?, direction: UIPageViewControllerNavigationDirection, animated: Bool, completion: (@escaping (Bool) -> Void)? = nil) {
pageViewController?.setViewControllers(viewControllers, direction: direction, animated: animated, completion: completion) pageViewController?.setViewControllers(viewControllers, direction: direction, animated: animated, completion: completion)
preparePageTabBarItems() preparePageTabBarItems()
} }
} }
extension PageController: UIPageViewControllerDelegate { extension PageTabBarController: UIPageViewControllerDelegate {
public func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) { public func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
guard let vc = pendingViewControllers.first else { guard let vc = pendingViewControllers.first else {
return return
...@@ -215,19 +250,11 @@ extension PageController: UIPageViewControllerDelegate { ...@@ -215,19 +250,11 @@ extension PageController: UIPageViewControllerDelegate {
return return
} }
guard let vc = previousViewControllers.first else { pageTabBar.select(at: selectedIndex)
return
}
guard let _ = viewControllers.index(of: vc) else {
return
}
tabBar.select(at: selectedIndex)
} }
} }
extension PageController: UIPageViewControllerDataSource { extension PageTabBarController: UIPageViewControllerDataSource {
public func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? { public func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
guard let current = viewControllers.index(of: viewController) else { guard let current = viewControllers.index(of: viewController) else {
return nil return nil
...@@ -258,18 +285,18 @@ extension PageController: UIPageViewControllerDataSource { ...@@ -258,18 +285,18 @@ extension PageController: UIPageViewControllerDataSource {
} }
} }
extension PageController: UIScrollViewDelegate { extension PageTabBarController: UIScrollViewDelegate {
public func scrollViewDidScroll(_ scrollView: UIScrollView) { public func scrollViewDidScroll(_ scrollView: UIScrollView) {
guard 0 < view.width else { guard 0 < view.width else {
return return
} }
guard let selected = tabBar.selected else { guard let selected = pageTabBar.selected else {
return return
} }
let x = (scrollView.contentOffset.x - view.width) / scrollView.contentSize.width * view.width let x = (scrollView.contentOffset.x - view.width) / scrollView.contentSize.width * view.width
tabBar.line.x = selected.x + x pageTabBar.line.x = selected.x + x
} }
} }
...@@ -110,7 +110,7 @@ open class TabBar: View { ...@@ -110,7 +110,7 @@ open class TabBar: View {
} }
/// The currently selected button. /// The currently selected button.
open var selected: UIButton? open internal(set) var selected: UIButton?
/// Buttons. /// Buttons.
open var buttons = [UIButton]() { open var buttons = [UIButton]() {
...@@ -125,6 +125,19 @@ open class TabBar: View { ...@@ -125,6 +125,19 @@ open class TabBar: View {
} }
} }
/// A boolean to animate the line when touched.
open var isLineAnimated = true {
didSet {
for b in buttons {
if isLineAnimated {
prepareLineAnimationHandler(button: b)
} else {
removeLineAnimationHandler(button: b)
}
}
}
}
/// A reference to the line UIView. /// A reference to the line UIView.
internal var line: UIView! internal var line: UIView!
...@@ -167,8 +180,9 @@ open class TabBar: View { ...@@ -167,8 +180,9 @@ open class TabBar: View {
b.grid.columns = columns b.grid.columns = columns
b.contentEdgeInsets = .zero b.contentEdgeInsets = .zero
b.layer.cornerRadius = 0 b.layer.cornerRadius = 0
b.removeTarget(self, action: #selector(handleButton(button:)), for: .touchUpInside) if isLineAnimated {
b.addTarget(self, action: #selector(handleButton(button:)), for: .touchUpInside) prepareLineAnimationHandler(button: b)
}
} }
grid.reload() grid.reload()
...@@ -205,7 +219,7 @@ open class TabBar: View { ...@@ -205,7 +219,7 @@ open class TabBar: View {
- Parameter to button: A UIButton. - Parameter to button: A UIButton.
- Paramater completion: An optional completion block. - Paramater completion: An optional completion block.
*/ */
internal func animate(to button: UIButton, completion: (@escaping (UIButton) -> Void)? = nil) { open func animate(to button: UIButton, completion: (@escaping (UIButton) -> Void)? = nil) {
delegate?.tabBarWillSelectButton?(tabBar: self, button: button) delegate?.tabBarWillSelectButton?(tabBar: self, button: button)
selected = button selected = button
...@@ -253,4 +267,21 @@ open class TabBar: View { ...@@ -253,4 +267,21 @@ open class TabBar: View {
private func prepareDivider() { private func prepareDivider() {
divider = Divider(view: self) divider = Divider(view: self)
} }
/**
Prepares the line animation handlers.
- Parameter button: A UIButton.
*/
private func prepareLineAnimationHandler(button: UIButton) {
removeLineAnimationHandler(button: button)
button.addTarget(self, action: #selector(handleButton(button:)), for: .touchUpInside)
}
/**
Removes the line animation handlers.
- Parameter button: A UIButton.
*/
private func removeLineAnimationHandler(button: UIButton) {
button.removeTarget(self, action: #selector(handleButton(button:)), for: .touchUpInside)
}
} }
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