Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce performInitialUpdate to allow disabling updates during view controller building #147

Merged
merged 1 commit into from
Jun 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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