CocoaPods trunk is moving to be read-only. Read more on the blog, there are 19 months to go.

RxContainer 0.8.5

RxContainer 0.8.5

TestsTested
LangLanguage SwiftSwift
License MIT
ReleasedLast Release Apr 2018
SPMSupports SPM

Maintained by Adrian Zubarev.



 
Depends on:
RxSwift~> 4.0
RxCocoa~> 4.0
 


This Swift module introduces a minimal custom ContainerViewController, which does not contain any unnecessary APIs like UINavigationViewController, nor rely on any protocols such as UIViewControllerTransitioningDelegate etc. for custom transitions.

The end-user is resposible to create custom animators, by conforming to the minimal Animator protocol, which will drive the transitions on the container-view-controller. The ContainerViewController has three different options for pop or push transitions: animated, interactive and immediate.

ContainerViewController:
open class ContainerViewController : UIViewController {
    ///
    open protocol Delegate : AnyObject {
        ///
        func animator(for transition: Transition) -> Animator?
    }

    ///
    public struct Event {
        ///
        public enum Position { case start, end }

        ///
        public let operation: Operation

        ///
        public var position: Position { get }

        ///
        public let containerViewController: ContainerViewController
    }

    ///
    public struct Operation {
        ///
        public enum Kind {
            case push(UIViewController)
            case pop(UIViewController)
            case set([UIViewController])
        }
        
        ///
        public let kind: Kind

        ///
        public let isAnimated: Bool
    }
    
    ///
    public enum Option {
        case animated, interactive, immediate
    }
    
    ///
    open var containerView: UIView { get }

    ///
    open var viewControllers: [UIViewController]

    ///
    open var rootViewController: UIViewController? { get }

    ///
    open var topViewController: UIViewController? { get }

    ///
    open weak var delegate: Delegate?

    /// Initializes and returns a newly created container view controller.
    public init()

    /// Initializes and returns a newly created container view controller.
    ///
    /// This is a convenience method for initializing the receiver and
    /// pushing view controllers onto the view controller stack. Every
    /// view controller stack must have at least one view controller to 
    /// act as the root.
    public convenience init(_ viewControllers: UIViewController...)

    /// Initializes and returns a newly created container view controller.
    ///
    /// This is a convenience method for initializing the receiver and
    /// pushing view controllers onto the view controller stack. Every
    /// view controller stack must have at least one view controller to 
    /// act as the root.
    public convenience init(_ viewControllers: [UIViewController])

    ///
    required public init?(coder aDecoder: NSCoder)

    ///
    open func push(
        _ viewController: UIViewController, 
        option: Option = .animated, 
        with animator: (Transition) -> Animator = RxContainer.animator(for:)
    )
    
    ///
    @discardableResult
    open func pop(
        option: Option = .animated, 
        with animator: (Transition) -> Animator = RxContainer.animator(for:)
    ) -> UIViewController?
    
    ///
    @discardableResult
    open func pop(
        to viewController: UIViewController, 
        option: Option = .animated,
        with animator: (Transition) -> Animator = RxContainer.animator(for:)
    ) -> [UIViewController]?
    
    ///
    @discardableResult
    open func popToRootViewController(
        option: Option = .animated,
        with animator: (Transition) -> Animator = RxContainer.animator(for:)
    ) -> [UIViewController]?
    
    ///
    open func setViewControllers(
        _ viewControllers: [UIViewController], 
        option: Option = .animated,
        with animator: (Transition) -> Animator = RxContainer.animator(for:)
    )
}

Reactive extension:

extension Reactive where Base : ContainerViewController {
	///
	public var event: Signal<ContainerViewController.Event>
}
Transition:
public final class Transition {
    ///
    public enum CompletionPosition { case start, end }

    ///
    public struct Context {

        ///
        public enum Key { case from, to }

        ///
        public enum Kind { case push, pop }

        ///
        public let kind: Kind

        ///
        public let containerView: UIView

        ///
        public let isAnimated: Bool

        ///
        public let isInteractive: Bool

        ///
        public func viewController(forKey key: Key) -> UIViewController

        ///
        public func view(forKey key: Key) -> UIView
    }

    ///
    public var additionalAnimation: ((Context) -> Void)? { get }
    
    ///
    public var additionalCompletion: ((Context) -> Void)? { get }
    
    ///
    public let context: Context
    
    ///
    public func animateAlongside(_ animation: ((Context) -> Void)?)
    
    ///
    public func animateAlongside(
        _ animation: ((Context) -> Void)?, 
        completion: ((Context) -> Void)? = default
    )

    ///
    public func complete(at position: CompletionPosition)
}
Animator:
open protocol Animator : AnyObject {
    ///
    var transition: Transition { get }

    ///
    func animate()
    
    // Default implementation (no-op)
    func transition(completed: Bool)
}
DefaultAnimator:
public final class DefaultAnimator : Animator {
    ///
    public enum Direction { case left, right, up, down }

    ///
    public enum Style { case overlap, slide }    
    
    ///
    public enum Order { case normal, reversed }

    ///
    public let transition: Transition

    ///
    public let direction: Direction
    
    ///
    public let style: Style

    ///
    public let order: Order

    ///
    public init(
        for transition: Transition,
        withDirection direction: Direction,
        style: Style = .overlap,
        order: Order = .normal
    )

    ///
    public func animate()
}

/// Default function for any transition.
public func animator(for transition: Transition) -> Animator