Skip to content

Commit

Permalink
Merge pull request #147 from square/kve/performInitialUpdate
Browse files Browse the repository at this point in the history
Introduce performInitialUpdate to allow disabling updates during view controller building
  • Loading branch information
kyleve authored Jun 23, 2022
2 parents 97296d0 + cb2c41d commit 62774aa
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 8 deletions.
9 changes: 7 additions & 2 deletions WorkflowUI/Sources/Screen/ScreenViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,13 @@
/// Convenience to create a view controller description for the given screen
/// value. See the example on the comment for ScreenViewController for
/// usage.
public final class func description(for screen: ScreenType, environment: ViewEnvironment) -> ViewControllerDescription {
return ViewControllerDescription(
public final class func description(
for screen: ScreenType,
environment: ViewEnvironment,
performInitialUpdate: Bool = true
) -> ViewControllerDescription {
ViewControllerDescription(
performInitialUpdate: performInitialUpdate,
type: self,
build: { self.init(screen: screen, environment: environment) },
update: { $0.update(screen: screen, environment: environment) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@
/// methods such as `buildViewController()`, `update(viewController:)`, if you are
/// manually managing your own view controller hierarchy.
public struct ViewControllerDescription {
/// If an initial call to `update(viewController:)` will be performed
/// when the view controller is created. Defaults to `true`.
///
/// ### Note
/// When creating container view controllers that contain other view controllers
/// (eg, a navigation stack), you usually want to set this value to `false` to avoid
/// duplicate updates to your children if they are created in `init`.
public var performInitialUpdate: Bool = true

private let viewControllerType: UIViewController.Type
private let build: () -> UIViewController
private let checkViewControllerType: (UIViewController) -> Bool
Expand All @@ -43,13 +52,24 @@
/// build and update a specific view controller type.
///
/// - Parameters:
/// - performInitialUpdate: If an initial call to `update(viewController:)`
/// will be performed when the view controller is created. Defaults to `true`.
///
/// - type: The type of view controller produced by this description.
/// Typically, should should be able to omit this parameter, but
/// in cases where type inference has trouble, it’s offered as
/// an escape hatch.
/// Typically, should should be able to omit this parameter, but
/// in cases where type inference has trouble, it’s offered as
/// an escape hatch.
///
/// - build: Closure that produces a new instance of the view controller
///
/// - update: Closure that updates the given view controller
public init<VC: UIViewController>(type: VC.Type = VC.self, build: @escaping () -> VC, update: @escaping (VC) -> Void) {
public init<VC: UIViewController>(
performInitialUpdate: Bool = true,
type: VC.Type = VC.self,
build: @escaping () -> VC,
update: @escaping (VC) -> Void
) {
self.performInitialUpdate = performInitialUpdate
self.viewControllerType = type
self.build = build
self.checkViewControllerType = { $0 is VC }
Expand All @@ -66,8 +86,10 @@
public func buildViewController() -> UIViewController {
let viewController = build()

// Perform an initial update of the built view controller
update(viewController: viewController)
if performInitialUpdate {
// Perform an initial update of the built view controller
update(viewController: viewController)
}

return viewController
}
Expand Down
18 changes: 18 additions & 0 deletions WorkflowUI/Tests/ViewControllerDescriptionTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,24 @@
XCTAssertFalse(description.canUpdate(viewController: UIViewController()))
}

func test_performInitialUpdate() {
var updateCount = 0
let description = ViewControllerDescription(
performInitialUpdate: false,
build: { BlankViewController() },
update: { _ in updateCount += 1 }
)

XCTAssertEqual(updateCount, 0)

// Build should not cause an initial update when
let viewController = description.buildViewController()
XCTAssertEqual(updateCount, 0)

description.update(viewController: viewController)
XCTAssertEqual(updateCount, 1)
}

func test_update() {
var updateCount = 0
let description = ViewControllerDescription(
Expand Down

0 comments on commit 62774aa

Please sign in to comment.