Skip to content

Instantly share code, notes, and snippets.

@saniul
Created January 23, 2015 09:11
Show Gist options
  • Save saniul/6fc728bbbc6e87fdf17d to your computer and use it in GitHub Desktop.
Save saniul/6fc728bbbc6e87fdf17d to your computer and use it in GitHub Desktop.
UINavigationBar styling between UINavigationController transitions
// NavStyleBug
//
// Created by Saniul Ahmed on 22/01/2015.
// Copyright (c) 2015 Saniul Ahmed. All rights reserved.
//
import UIKit
//MARK: Environment
@objc
protocol Styleable {
var barStyle: UIBarStyle { get }
}
class ViewControllerA: UIViewController, Styleable {
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Default"
}
var barStyle: UIBarStyle {
return .Default
}
}
class ViewControllerB: UIViewController, Styleable {
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Black"
}
var barStyle: UIBarStyle {
return .Black
}
}
class NavController: UINavigationController {
var stylingDelegate: StylingNavigationDelegate?
override func viewDidLoad() {
self.stylingDelegate = StylingNavigationDelegate(navigationController: self)
self.delegate = self.stylingDelegate
}
}
@objc
class StylingNavigationDelegate: NSObject, UINavigationControllerDelegate {
var navigationController: UINavigationController
var popTransitionHelper: InteractivePopTransitionHelper
init(navigationController: UINavigationController) {
self.navigationController = navigationController
self.popTransitionHelper = InteractivePopTransitionHelper(navigationController: navigationController)
super.init()
self.popTransitionHelper.began = self.interactivePopTransitionBegan
}
func updateBarStyleWith(barStyle: UIBarStyle) {
self.navigationController.navigationBar.barStyle = barStyle
}
//If we only do this, we will have a problem when cancelling the interactive pop transition
func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) {
if let styleable = navigationController.topViewController as? Styleable {
self.updateBarStyleWith(styleable.barStyle)
}
}
//This restores the bar style to what it was at the beginning of the gesture.
func interactivePopTransitionBegan() {
let preTransitionStyle = self.navigationController.navigationBar.barStyle
self.popTransitionHelper.finished = { cancelled in
if cancelled {
self.updateBarStyleWith(preTransitionStyle)
}
}
}
}
//MARK: Interactive Pop Transition Helper
@objc
public final class InteractivePopTransitionHelper {
public let navigationController: UINavigationController
public var began: (() -> Void)?
public var finished: (Bool -> Void)?
public init(navigationController: UINavigationController) {
self.navigationController = navigationController
navigationController.interactivePopGestureRecognizer.addTarget(self, action: Selector("interactivePopGestureRecognizerUpdate:"))
}
private final func interactivePopGestureRecognizerUpdate(gesture: UIGestureRecognizer) {
if gesture.state != .Began {
return;
}
if let coordinator = self.navigationController.transitionCoordinator() {
self.began?()
coordinator.notifyWhenInteractionEndsUsingBlock { context -> Void in
self.finished?(context.isCancelled())
() //argh, swift :(
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment