Skip to content

Commit

Permalink
Add method to return result when popping navigation stack
Browse files Browse the repository at this point in the history
  • Loading branch information
Lukas Vyletel committed Sep 23, 2019
1 parent c415bb1 commit e383885
Show file tree
Hide file tree
Showing 11 changed files with 123 additions and 7 deletions.
20 changes: 20 additions & 0 deletions AppFoundation.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
07E22EC621C78F3400D2884E /* StringConvertibleMembers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07E22EC521C78F3400D2884E /* StringConvertibleMembers.swift */; };
07E22EC921C78FFA00D2884E /* Styles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07E22EC721C78FBE00D2884E /* Styles.swift */; };
07E22ECD21C7938A00D2884E /* StyledButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07E22ECC21C7938A00D2884E /* StyledButton.swift */; };
07E49AE72338A40600DFF5F8 /* SixthCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07E49AE62338A40600DFF5F8 /* SixthCoordinator.swift */; };
07E49AE92338A43F00DFF5F8 /* SixthViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07E49AE82338A43F00DFF5F8 /* SixthViewController.swift */; };
07E49AEB2338A47500DFF5F8 /* SixthViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07E49AEA2338A47500DFF5F8 /* SixthViewModel.swift */; };
07F380E2228AC15800800A81 /* RxRelay.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 07F380E1228AC15800800A81 /* RxRelay.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
80450CCC21B3CF5100611C65 /* FirstViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80450CCB21B3CF5100611C65 /* FirstViewModel.swift */; };
80450CD821B45E8000611C65 /* SecondViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80450CD721B45E8000611C65 /* SecondViewController.swift */; };
Expand Down Expand Up @@ -133,6 +136,9 @@
07E22EC521C78F3400D2884E /* StringConvertibleMembers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringConvertibleMembers.swift; sourceTree = "<group>"; };
07E22EC721C78FBE00D2884E /* Styles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Styles.swift; sourceTree = "<group>"; };
07E22ECC21C7938A00D2884E /* StyledButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StyledButton.swift; sourceTree = "<group>"; };
07E49AE62338A40600DFF5F8 /* SixthCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SixthCoordinator.swift; sourceTree = "<group>"; };
07E49AE82338A43F00DFF5F8 /* SixthViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SixthViewController.swift; sourceTree = "<group>"; };
07E49AEA2338A47500DFF5F8 /* SixthViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SixthViewModel.swift; sourceTree = "<group>"; };
07F380E1228AC15800800A81 /* RxRelay.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RxRelay.framework; path = Carthage/Build/iOS/RxRelay.framework; sourceTree = "<group>"; };
8031C14F21BCF67F0066394B /* UIViewController+Rx.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+Rx.swift"; sourceTree = "<group>"; };
8031C15121BCF99D0066394B /* Exceptions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Exceptions.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -276,6 +282,16 @@
path = Utils;
sourceTree = "<group>";
};
07E49AE52338A3C500DFF5F8 /* Sixth Screen */ = {
isa = PBXGroup;
children = (
07E49AE62338A40600DFF5F8 /* SixthCoordinator.swift */,
07E49AE82338A43F00DFF5F8 /* SixthViewController.swift */,
07E49AEA2338A47500DFF5F8 /* SixthViewModel.swift */,
);
path = "Sixth Screen";
sourceTree = "<group>";
};
80450CCA21B3CD2A00611C65 /* Screens */ = {
isa = PBXGroup;
children = (
Expand All @@ -288,6 +304,7 @@
80F8DB1221BDA38C0051900E /* Third Screen */,
07346E6321E8F6D8005DCF06 /* Fourth Screen */,
074A81EE2202E05500C4302D /* Fifth Screen */,
07E49AE52338A3C500DFF5F8 /* Sixth Screen */,
);
path = Screens;
sourceTree = "<group>";
Expand Down Expand Up @@ -512,10 +529,13 @@
074A81F42202E09300C4302D /* FifthViewModel.swift in Sources */,
80F8DB0F21BDA2ED0051900E /* SecondCoordinator.swift in Sources */,
074A81F22202E08A00C4302D /* FifthCoordinator.swift in Sources */,
07E49AE92338A43F00DFF5F8 /* SixthViewController.swift in Sources */,
07E49AE72338A40600DFF5F8 /* SixthCoordinator.swift in Sources */,
80F8DB1421BDA3A90051900E /* ThirdViewModel.swift in Sources */,
07292B3E21F1C0C1006F0369 /* Errors.swift in Sources */,
80B6A81421986270003E868C /* AppDelegate.swift in Sources */,
07346E6C21E8FB64005DCF06 /* FourthCoordinator.swift in Sources */,
07E49AEB2338A47500DFF5F8 /* SixthViewModel.swift in Sources */,
07346E6A21E8F995005DCF06 /* FourthViewModel.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
5 changes: 5 additions & 0 deletions AppFoundation/Core/Coordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ public extension Coordinator {
.navigationController?.viewControllers.suffix(popDepth + 1).first
else { return }
viewController.navigationController?.popToViewController(popTo, animated: animated)
case let .popWithResult(animated, result):
(viewController as? ResultProviderViewController)?
.resultListener
.publishResult(result)
viewController.navigationController?.popViewController(animated: animated)
case let .switchStoryboard(name, storyboardId, parameter):
let storyboard = UIStoryboard(name: name, bundle: nil)
let initialViewController = storyboard.instantiateViewController(
Expand Down
4 changes: 4 additions & 0 deletions AppFoundation/Core/Navigation+Result.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,8 @@ public extension ViewModel {
func dismissReturningResult<T: IsAnyEquatable & Equatable>(animated: Animated, result: T) {
events.accept(NavigationEvent.dismissWithResult(animated, result.asAnyEquatable()))
}

func popReturningResult<T: IsAnyEquatable & Equatable>(animated: Animated, result: T) {
events.accept(NavigationEvent.popWithResult(animated, result.asAnyEquatable()))
}
}
1 change: 1 addition & 0 deletions AppFoundation/Core/Navigation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public enum NavigationEvent: FoundationEvent, Equatable {
case dismiss(Animated)
case dismissWithResult(Animated, SegueParameter)
case pop(Animated, PopDepth)
case popWithResult(Animated, SegueParameter)
case switchStoryboard(StoryboardName, ViewControllerId, SegueParameter?)
}

Expand Down
21 changes: 17 additions & 4 deletions Example/OtherStoryboard.storyboard
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="q1w-1e-SHb">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="q1w-1e-SHb">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
Expand Down Expand Up @@ -92,16 +92,29 @@
</objects>
<point key="canvasLocation" x="41" y="788"/>
</scene>
<!--View Controller-->
<!--Sixth View Controller-->
<scene sceneID="XbZ-Pd-9Y0">
<objects>
<viewController id="OAP-Uq-CLc" sceneMemberID="viewController">
<viewController id="OAP-Uq-CLc" customClass="SixthViewController" customModule="AppFoundationExample" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="11d-02-77u">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Iob-sh-cbK">
<rect key="frame" x="133" y="318.5" width="109" height="30"/>
<state key="normal" title="Pop With Result"/>
</button>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="Iob-sh-cbK" firstAttribute="centerY" secondItem="11d-02-77u" secondAttribute="centerY" id="hgh-hU-wZV"/>
<constraint firstItem="Iob-sh-cbK" firstAttribute="centerX" secondItem="11d-02-77u" secondAttribute="centerX" id="mte-tr-xJS"/>
</constraints>
<viewLayoutGuide key="safeArea" id="BLQ-UW-OFM"/>
</view>
<connections>
<outlet property="popWithResultButton" destination="Iob-sh-cbK" id="xAX-fc-zMa"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="uwr-Tu-iAS" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
Expand Down
4 changes: 4 additions & 0 deletions Example/Screens/Contracts.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,7 @@ struct FifthIntents {
let dismiss: Driver<Void>
let dismissWithResult: Driver<Void>
}

struct SixthIntents {
let popWithResult: Driver<Void>
}
2 changes: 2 additions & 0 deletions Example/Screens/Fourth Screen/FourthCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ extension FourthCoordinator: SegueHandler {
switch segue.identifier {
case FourthSegues.modal.rawValue:
return FifthCoordinator(viewController: segue.destination())
case FourthSegues.nextScreen.rawValue:
return SixthCoordinator(viewController: segue.destination())
default: return nil
}
}
Expand Down
12 changes: 9 additions & 3 deletions Example/Screens/Fourth Screen/FourthViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,15 @@ extension FourthViewModel: ViewModel {
Observable.just("Fourth state").subscribe(onNext: { value in
self.nextState { oldState in oldState.labelValue = value }
}),
intents.next.subscribe(onNext: {
self.navigatePerformSegue(segueIdentifier: FourthSegues.nextScreen)
}),
intents.next.flatMap { _ in
self.navigatePerformSegueForResult(
resultObservable: intents.result, segueIdentifier: FourthSegues.nextScreen
).do(onSuccess: { value in
self.nextState { newState in
newState.labelValue = "Result: \(value)"
}
})
}.subscribe(),
intents.present
.flatMap { _ in
self.navigatePerformSegueForResult(
Expand Down
21 changes: 21 additions & 0 deletions Example/Screens/Sixth Screen/SixthCoordinator.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import AppFoundation

struct SixthCoordinator: VMMCoordinator {
let viewController: Weak<SixthViewController>

init(viewController: SixthViewController) {
self.viewController = asWeak(value: viewController)
}
}

extension SixthCoordinator: SegueHandler {
func coordinator(for segue: UIStoryboardSegue, sender: Any?) -> Coordinator? {
return nil
}
}

extension SixthCoordinator: ViewModelProvider {
func provide() -> SixthViewModel {
return SixthViewModel()
}
}
22 changes: 22 additions & 0 deletions Example/Screens/Sixth Screen/SixthViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import AppFoundation
import RxSwift
import UIKit

class SixthViewController: UIViewController {
let disposeBag: DisposeBag = DisposeBag()
var coordinator: Coordinator!
var resultListener: ResultListener!
@IBOutlet weak var popWithResultButton: UIButton!
}

extension SixthViewController: Screen {
var intents: SixthIntents {
return SixthIntents(
popWithResult: popWithResultButton.rx.tap.asDriver()
)
}

func render(state: String) {}
}

extension SixthViewController: ResultProviderViewController {}
18 changes: 18 additions & 0 deletions Example/Screens/Sixth Screen/SixthViewModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import AppFoundation
import RxCocoa
import RxSwift

struct SixthViewModel {
let events: PublishRelay<FoundationEvent> = PublishRelay<FoundationEvent>()
let state: BehaviorRelay<String> = BehaviorRelay(value: "")
}

extension SixthViewModel: ViewModel {
func collectIntents(intents: SixthIntents) -> CompositeDisposable {
return CompositeDisposable(disposables: [
intents.popWithResult
.do(onNext: { self.popReturningResult(animated: true, result: "Sixth popped") })
.drive()
])
}
}

0 comments on commit e383885

Please sign in to comment.