Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into feature/swift4.2
Browse files Browse the repository at this point in the history
  • Loading branch information
br-tyler-milner committed Aug 17, 2018
2 parents a286398 + e394935 commit 457844f
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ class BaseContainerViewController: UIViewController {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.

containerViewController.managedChildren = [Child(title: "A", viewController: controllerA),
Child(title: "B", viewController: controllerB)]
containerViewController.managedChildren = [Child(identifier: "A", viewController: controllerA),
Child(identifier: "B", viewController: controllerB)]

containerViewController.willMove(toParentViewController: self)
addChildViewController(containerViewController)
Expand All @@ -36,11 +36,11 @@ class BaseContainerViewController: UIViewController {
}

@IBAction func transitionToA() {
containerViewController.transitionToController(withTitle: "A")
containerViewController.transitionToController(withIdentifier: "A")
}

@IBAction func transitionToB() {
containerViewController.transitionToController(withTitle: "B")
containerViewController.transitionToController(withIdentifier: "B")
}

@IBAction func logSwitchDidChange(_ sender: UISwitch) {
Expand All @@ -56,9 +56,9 @@ class BaseContainerViewController: UIViewController {

//MARK: Helper
fileprivate extension ContainerViewController {
func transitionToController(withTitle title: String) {
func transitionToController(withIdentifier identifier: AnyHashable) {
//Note: As titles can change rapidly, it is much safer to directly use the Child object.
guard let child = managedChildren.first(where: { $0.title == title }) else { return }
guard let child = managedChildren.first(where: { $0.identifier == identifier }) else { return }
transitionToController(for: child)
}
}
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ func addOneHourTo(date: Date) -> Date {
A solution for managing multiple child view controllers, the ContainerViewController manages the lifecycle of the child controllers. This allows you to focus on the navigational structure of your views as well as the transitions between them.

``` swift
containerViewController.managedChildren = [Child(title: "A", viewController: controllerA), Child(title: "B", viewController: controllerB)]
containerViewController.managedChildren = [Child(identifier: "A", viewController: controllerA), Child(identifier: "B", viewController: controllerB)]

containerViewController.willMove(toParentViewController: self)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import UIKit

public extension ContainerViewController {

//MARK: Finding a Child
//MARK: Finding a ManagedChild
func index(ofChild controller: UIViewController) -> Int? {
return managedChildren.index(where: { $0.viewController === controller })
}
Expand All @@ -32,7 +32,7 @@ public extension ContainerViewController {
#endif
}

func removeChildren(where predicate: (Child) -> Bool) {
func removeChildren(where predicate: (ManagedChild) -> Bool) {
managedChildren.filter(predicate).forEach(removeChild)
}
}
29 changes: 5 additions & 24 deletions Sources/UtiliKit/Container/ContainerViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,10 @@

import UIKit

//MARK: Child Subtype
public struct Child: Equatable {
public let title: String
public let viewController: UIViewController

public init(title: String, viewController: UIViewController) {
self.title = title
self.viewController = viewController
}

public init<T: RawRepresentable>(title: T, viewController: UIViewController) where T.RawValue == String {
self.init(title: title.rawValue, viewController: viewController)
}

public static func ==(lhs: Child, rhs: Child) -> Bool {
return lhs.title == rhs.title && lhs.viewController === rhs.viewController
}
}

open class ContainerViewController: UIViewController {

//MARK: Properties
public var managedChildren: [Child] = []
public var managedChildren: [ManagedChild] = []
public private(set) var isTransitioning: Bool = false
public var shouldAutomaticallyTransitionOnLoad: Bool = true
public var visibleController: UIViewController? {
Expand All @@ -46,7 +27,7 @@ open class ContainerViewController: UIViewController {
public weak var delegate: ContainerViewControllerDelegate?

//MARK: Initializers
public convenience init(managedChildren: [Child], delegate: ContainerViewControllerDelegate? = nil) {
public convenience init(managedChildren: [ManagedChild], delegate: ContainerViewControllerDelegate? = nil) {
self.init(nibName: nil, bundle: nil)
self.managedChildren = managedChildren
self.delegate = delegate
Expand All @@ -72,15 +53,15 @@ open class ContainerViewController: UIViewController {
//MARK: Public Interface
extension ContainerViewController {

open func transitionToController(for child: Child, completion: ((Bool) -> Void)? = nil) {
if !managedChildren.contains(child) {
open func transitionToController(for child: ManagedChild, completion: ((Bool) -> Void)? = nil) {
if !managedChildren.contains { $0.viewController === child.viewController } {
managedChildren.append(child)
}

transition(to: child.viewController, completion: completion)
}

open func child(at index: Int) -> Child? {
open func child(at index: Int) -> ManagedChild? {
guard index >= managedChildren.startIndex && index < managedChildren.endIndex else { return nil }
return managedChildren[index]
}
Expand Down
29 changes: 29 additions & 0 deletions Sources/UtiliKit/Container/ManagedChild.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// ManagedChild.swift
// UtiliKit-iOS
//
// Created by Cuong Ngo on 8/14/18.
// Copyright © 2018 CocoaPods. All rights reserved.
//

import UIKit

public protocol ManagedChild {
var identifier: AnyHashable { get }
var viewController: UIViewController { get }
}

//MARK: Simple Child Implementation
public struct Child: ManagedChild {
public let identifier: AnyHashable
public let viewController: UIViewController

public init(identifier: AnyHashable, viewController: UIViewController) {
self.identifier = identifier
self.viewController = viewController
}

public init<T: RawRepresentable>(title: T, viewController: UIViewController) where T.RawValue == String {
self.init(identifier: title.rawValue, viewController: viewController)
}
}
16 changes: 8 additions & 8 deletions Tests/ContainerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ class ContainerTests: XCTestCase {

func test_Container_indexOfChild() {
let viewController = UIViewController()
let children = [Child(title: "title", viewController: viewController),
Child(title: "title2", viewController: UIViewController())]
let children = [Child(identifier: "title", viewController: viewController),
Child(identifier: "title2", viewController: UIViewController())]

let container = ContainerViewController(managedChildren: children)
XCTAssertNil(container.index(ofChild: UIViewController()))
Expand All @@ -24,19 +24,19 @@ class ContainerTests: XCTestCase {

func test_Container_indexOfChildFollowing() {
let viewController = UIViewController()
let children = [Child(title: "title", viewController: viewController),
Child(title: "title2", viewController: UIViewController())]
let children = [Child(identifier: "title", viewController: viewController),
Child(identifier: "title2", viewController: UIViewController())]

let container = ContainerViewController(managedChildren: children)
XCTAssertEqual(container.indexOfChild(following: viewController), 1)
XCTAssertNil(container.indexOfChild(following: UIViewController()))
}

func test_Container_childAtIndex() {
let children = [Child(title: "title", viewController: UIViewController()),
Child(title: "title2", viewController: UIViewController()),
Child(title: "title3", viewController: UIViewController()),
Child(title: "title4", viewController: UIViewController())]
let children = [Child(identifier: "title", viewController: UIViewController()),
Child(identifier: "title2", viewController: UIViewController()),
Child(identifier: "title3", viewController: UIViewController()),
Child(identifier: "title4", viewController: UIViewController())]

let container = ContainerViewController(managedChildren: children)

Expand Down
14 changes: 14 additions & 0 deletions UtiliKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
0E6E8C6D2112551200617815 /* ContainerViewController+ManagedChildren.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E6E8C6C2112551200617815 /* ContainerViewController+ManagedChildren.swift */; };
0EC8025C209CE9C90051F732 /* Configurable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EC8025B209CE9C90051F732 /* Configurable.swift */; };
0ED9476420FD473700B642AB /* ContainerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ED9476220FD461300B642AB /* ContainerTests.swift */; };
1D419DBD21235EE100B62D91 /* ManagedChild.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D419DBC21235EE100B62D91 /* ManagedChild.swift */; };
1D419DBF21236CC300B62D91 /* UtiliKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8677313920601BB400C54343 /* UtiliKit.framework */; };
8677314220601BB400C54343 /* UtiliKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8677313920601BB400C54343 /* UtiliKit.framework */; };
8677315720601D1A00C54343 /* UtiliKitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 869826261FE87BFA0024B73D /* UtiliKitTests.swift */; };
8677315820601D1A00C54343 /* DateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 869826271FE87BFA0024B73D /* DateTests.swift */; };
Expand Down Expand Up @@ -78,6 +80,7 @@
0E6E8C6C2112551200617815 /* ContainerViewController+ManagedChildren.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ContainerViewController+ManagedChildren.swift"; sourceTree = "<group>"; };
0EC8025B209CE9C90051F732 /* Configurable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Configurable.swift; sourceTree = "<group>"; };
0ED9476220FD461300B642AB /* ContainerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContainerTests.swift; sourceTree = "<group>"; };
1D419DBC21235EE100B62D91 /* ManagedChild.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManagedChild.swift; sourceTree = "<group>"; };
8677313920601BB400C54343 /* UtiliKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = UtiliKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
8677314120601BB400C54343 /* UtiliKit-iOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "UtiliKit-iOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
8677315A20601DD800C54343 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
Expand Down Expand Up @@ -157,19 +160,28 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
1D419DBF21236CC300B62D91 /* UtiliKit.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
1D419DBE21236CC300B62D91 /* Frameworks */ = {
isa = PBXGroup;
children = (
);
name = Frameworks;
sourceTree = "<group>";
};
607FACC71AFB9204008FA782 = {
isa = PBXGroup;
children = (
8698CFCB2061A0FB0065AE20 /* Examples */,
8698CF9D20619EAD0065AE20 /* Sources */,
607FACE81AFB9204008FA782 /* Tests */,
607FACD11AFB9204008FA782 /* Products */,
1D419DBE21236CC300B62D91 /* Frameworks */,
);
sourceTree = "<group>";
};
Expand Down Expand Up @@ -240,6 +252,7 @@
0E6E8C6C2112551200617815 /* ContainerViewController+ManagedChildren.swift */,
8698CFA520619EAD0065AE20 /* ContainerViewControllerDelegate.swift */,
8698CFA620619EAD0065AE20 /* ContainerViewControllerTransitionAnimator.swift */,
1D419DBC21235EE100B62D91 /* ManagedChild.swift */,
);
path = Container;
sourceTree = "<group>";
Expand Down Expand Up @@ -540,6 +553,7 @@
8698CFBA20619EAD0065AE20 /* ContainerTransitionContext.swift in Sources */,
8698CFBE20619EAD0065AE20 /* FileManager+Extensions.swift in Sources */,
8698CFBD20619EAD0065AE20 /* ContainerViewControllerTransitionAnimator.swift in Sources */,
1D419DBD21235EE100B62D91 /* ManagedChild.swift in Sources */,
8698CFBC20619EAD0065AE20 /* ContainerViewControllerDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down

0 comments on commit 457844f

Please sign in to comment.