Skip to content

Commit

Permalink
Merge pull request #12 from trafi/feature/presenting-during-unwind
Browse files Browse the repository at this point in the history
Allow presenting during unwind
  • Loading branch information
Domas Nutautas authored May 21, 2020
2 parents 17c23bd + a3539b1 commit 338c75a
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 4 deletions.
32 changes: 29 additions & 3 deletions Sources/StoryFlow/Flow/Helpers/Transition.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,31 @@ public struct Transition<To: UIViewController> {
extension Transition {

public static func custom(_: To.Type, transition: @escaping (UIViewController, To) -> ()) -> Transition {
return Transition(go: transition)
return Transition { from, to in
from.afterDismissingCompleted {
transition(from, to)
}
}
}

public static func show(_: To.Type) -> Transition {
return Transition { $0.show($1, sender: nil) }
return Transition { from, to in
if from.navigationController != nil {
from.show(to, sender: nil)
} else {
from.afterDismissingCompleted {
from.show(to, sender: nil)
}
}
}
}

public static func present(_: To.Type, animated: Bool = true) -> Transition {
return Transition { $0.present($1, animated: animated) }
return Transition { from, to in
from.afterDismissingCompleted {
from.present(to, animated: animated)
}
}
}
}

Expand All @@ -30,6 +46,8 @@ extension Transition where To == UIViewController {
let parentInTab = $1.parentInTabBarController
let isWrongTab = parentInTab != $1.tabBarController?.selectedViewController
let isPresenting = $1.presentedViewController != nil
&& $1.presentedViewController?.isBeingPresented == false
&& $1.presentedViewController?.isBeingDismissed == false

// 1. Navigation pop
if let nav = $1.navigationController {
Expand All @@ -55,4 +73,12 @@ private extension UIViewController {
var parentInTabBarController: UIViewController? {
self.parent == self.tabBarController ? self : self.parent?.parentInTabBarController
}

func afterDismissingCompleted(_ transition: @escaping () -> ()) {
if presentedViewController?.isBeingDismissed == true {
dismiss(animated: true, completion: transition)
} else {
transition()
}
}
}
2 changes: 1 addition & 1 deletion Sources/StoryFlow/Flow/ImplicitFlow/ImplicitFlow.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ extension Flow {
if let to = Flow<Any>.destination(for: output) {
let transition = TransitionInfo(from: from, producedType: output.type, receivedType: type, to: to, isUnwind: false)
if CustomTransition.attempt(transition) == false {
from.show(to, sender: nil)
Transition.show(UIViewController.self).go(from, to)
}
return
}
Expand Down
91 changes: 91 additions & 0 deletions StoryFlowTests/ImplicitFlowTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,33 @@ class ImplicitFlowTests: XCTestCase {
XCTAssert(currentVc is To)
}

// MARK: Present

func testProduce_whenDismissingPresented_itPresentsAfterDismiss() {

// Arrange
class T {}

class From: UIViewController, OutputProducing { typealias OutputType = T }
class To: UIViewController, InputRequiring { typealias InputType = T }

let from = From().visible()
from.present(UIViewController(), animated: true, completion: nil)
XCTAssert(currentVc.didAppear())

from.dismiss(animated: true, completion: nil)

let output = T()

// Act
from.produce(output)
XCTAssert(currentVc.didDismiss())

// Assert
XCTAssert(currentVc is To)

}

// MARK: Unwind

func testProduce_itUnwindsToUpdateHandlingVcAndPassesOutput() {
Expand Down Expand Up @@ -242,6 +269,7 @@ class ImplicitFlowTests: XCTestCase {

let from = From()
container.show(from, sender: nil)
XCTAssert(currentVc.didAppear())

let output = T()

Expand Down Expand Up @@ -330,6 +358,68 @@ class ImplicitFlowTests: XCTestCase {
XCTAssert(to.update === output)
}

func testProduce_whenParentIsPresentingDuringUnwind_itUnwindsWihtoutInteruptingPresentation() {

// Arrange
class T {}

class From: UIViewController, OutputProducing { typealias OutputType = T }
class To: UIViewController, UpdateHandling {
func handle(update: T) {
self.update = update
self.present(UIViewController(), animated: true, completion: nil)
}
var update: T!
}

let to = To().visible()
let from = From()

to.addChild(from)

let output = T()

// Act
from.produce(output)
XCTAssert(currentVc.didAppear())

// Assert
XCTAssert(currentVc == to.presentedViewController!)
XCTAssert(to.update === output)
}

func testProduce_whenPresentingDuringUnwind_itUnwindsWihtoutInteruptingPresentation() {

// Arrange
class T {}

class From: UIViewController, OutputProducing { typealias OutputType = T }
class To: UIViewController, UpdateHandling {
func handle(update: T) {
self.update = update
self.present(UIViewController(), animated: true, completion: nil)
}
var update: T!
}

let to = To()
let from = From()
UINavigationController(rootViewController: to).visible()

to.show(from, sender: nil)
XCTAssert(currentVc.didAppear())

let output = T()

// Act
from.produce(output)
XCTAssert(currentVc.didAppear())

// Assert
XCTAssert(currentVc == to.presentedViewController!)
XCTAssert(to.update === output)
}

func testProduce_whenSelfCanHandleUpdate_itUnwindsToPreviousVc() {

// Arrange
Expand Down Expand Up @@ -443,6 +533,7 @@ class ImplicitFlowTests: XCTestCase {

let from = From()
currentVc.show(from, sender: nil)
XCTAssert(currentVc.didAppear())

// TabBar
// - Navigation
Expand Down

0 comments on commit 338c75a

Please sign in to comment.