Skip to content

Commit 360bddd

Browse files
author
Michael Long
committed
Update navigation creation system for UINavigationControllers
1 parent fd17961 commit 360bddd

File tree

7 files changed

+76
-22
lines changed

7 files changed

+76
-22
lines changed

RxSwiftWidgets.xcodeproj/project.pbxproj

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
4C8CCF3122F0FB7E008139A3 /* BindableElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C8CCF3022F0FB7E008139A3 /* BindableElement.swift */; };
7070
4C8CCF3322F1DB32008139A3 /* DoneButtonWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C8CCF3222F1DB32008139A3 /* DoneButtonWidget.swift */; };
7171
4C8F4E34231470C5001997C8 /* WidgetTheme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C8F4E33231470C5001997C8 /* WidgetTheme.swift */; };
72+
4C9143AA233044D900260FC0 /* WidgetViewNavigating.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C9143A9233044D900260FC0 /* WidgetViewNavigating.swift */; };
7273
4CD6916C2306EFBC00C6FB9C /* TableWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CD6916B2306EFBC00C6FB9C /* TableWidget.swift */; };
7374
4CE3B69C22F49E1400E47F57 /* WidgetSwiftUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE3B69A22F49DFF00E47F57 /* WidgetSwiftUI.swift */; };
7475
4CE3B69E22F4BCBC00E47F57 /* WidgetAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE3B69D22F4BCBC00E47F57 /* WidgetAnimation.swift */; };
@@ -358,7 +359,7 @@
358359
OBJ_654 /* WidgetContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_12 /* WidgetContext.swift */; };
359360
OBJ_655 /* WidgetModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_13 /* WidgetModifier.swift */; };
360361
OBJ_656 /* WidgetModifying.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_14 /* WidgetModifying.swift */; };
361-
OBJ_657 /* WidgetNavigation.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_15 /* WidgetNavigation.swift */; };
362+
OBJ_657 /* WidgetNavigator.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_15 /* WidgetNavigator.swift */; };
362363
OBJ_658 /* WidgetPadding.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_16 /* WidgetPadding.swift */; };
363364
OBJ_659 /* WidgetPositioning.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_17 /* WidgetPositioning.swift */; };
364365
OBJ_660 /* WidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_18 /* WidgetView.swift */; };
@@ -596,6 +597,7 @@
596597
4C8CCF3022F0FB7E008139A3 /* BindableElement.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BindableElement.swift; sourceTree = "<group>"; };
597598
4C8CCF3222F1DB32008139A3 /* DoneButtonWidget.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DoneButtonWidget.swift; sourceTree = "<group>"; };
598599
4C8F4E33231470C5001997C8 /* WidgetTheme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetTheme.swift; sourceTree = "<group>"; };
600+
4C9143A9233044D900260FC0 /* WidgetViewNavigating.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetViewNavigating.swift; sourceTree = "<group>"; };
599601
4CD6916B2306EFBC00C6FB9C /* TableWidget.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableWidget.swift; sourceTree = "<group>"; };
600602
4CE3B69A22F49DFF00E47F57 /* WidgetSwiftUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetSwiftUI.swift; sourceTree = "<group>"; };
601603
4CE3B69D22F4BCBC00E47F57 /* WidgetAnimation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetAnimation.swift; sourceTree = "<group>"; };
@@ -659,7 +661,7 @@
659661
OBJ_147 /* UITabBarController+Rx.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITabBarController+Rx.swift"; sourceTree = "<group>"; };
660662
OBJ_148 /* UITabBarItem+Rx.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITabBarItem+Rx.swift"; sourceTree = "<group>"; };
661663
OBJ_149 /* UITableView+Rx.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITableView+Rx.swift"; sourceTree = "<group>"; };
662-
OBJ_15 /* WidgetNavigation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetNavigation.swift; sourceTree = "<group>"; };
664+
OBJ_15 /* WidgetNavigator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetNavigator.swift; sourceTree = "<group>"; };
663665
OBJ_150 /* UITextField+Rx.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITextField+Rx.swift"; sourceTree = "<group>"; };
664666
OBJ_151 /* UITextView+Rx.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITextView+Rx.swift"; sourceTree = "<group>"; };
665667
OBJ_152 /* UIView+Rx.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Rx.swift"; sourceTree = "<group>"; };
@@ -1645,12 +1647,13 @@
16451647
4C15DED422EDE4A900196894 /* WidgetDismissible.swift */,
16461648
OBJ_13 /* WidgetModifier.swift */,
16471649
OBJ_14 /* WidgetModifying.swift */,
1648-
OBJ_15 /* WidgetNavigation.swift */,
1650+
OBJ_15 /* WidgetNavigator.swift */,
16491651
OBJ_16 /* WidgetPadding.swift */,
16501652
OBJ_17 /* WidgetPositioning.swift */,
16511653
4CE3B69A22F49DFF00E47F57 /* WidgetSwiftUI.swift */,
16521654
4C8F4E33231470C5001997C8 /* WidgetTheme.swift */,
16531655
OBJ_18 /* WidgetView.swift */,
1656+
4C9143A9233044D900260FC0 /* WidgetViewNavigating.swift */,
16541657
);
16551658
path = Core;
16561659
sourceTree = "<group>";
@@ -2234,8 +2237,9 @@
22342237
OBJ_655 /* WidgetModifier.swift in Sources */,
22352238
4C120079230A244D003B060C /* UIControlWidget.swift in Sources */,
22362239
4C15DED622EDE5BB00196894 /* WidgetDismissible.swift in Sources */,
2240+
4C9143AA233044D900260FC0 /* WidgetViewNavigating.swift in Sources */,
22372241
OBJ_656 /* WidgetModifying.swift in Sources */,
2238-
OBJ_657 /* WidgetNavigation.swift in Sources */,
2242+
OBJ_657 /* WidgetNavigator.swift in Sources */,
22392243
OBJ_658 /* WidgetPadding.swift in Sources */,
22402244
OBJ_659 /* WidgetPositioning.swift in Sources */,
22412245
OBJ_660 /* WidgetView.swift in Sources */,

RxSwiftWidgetsDemo/AppDelegate.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UISplitViewControllerDele
2626
let widget = MainMenuWidget()
2727

2828
window = UIWindow(frame: UIScreen.main.bounds)
29-
let navigationController = UINavigationController()
30-
navigationController.addChild(widget.controller(with: WidgetContext()))
31-
window?.rootViewController = navigationController
29+
window?.rootViewController = widget.controller(with: WidgetContext())
3230
window?.makeKeyAndVisible()
3331

3432
return true

RxSwiftWidgetsDemo/Application/MainMenu/MainMenuWidget.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import UIKit
33
import RxSwiftWidgets
44

5-
struct MainMenuWidget: WidgetView {
5+
struct MainMenuWidget: WidgetView, WidgetViewNavigating {
66

77
func widget(_ context: WidgetContext) -> Widget {
88

@@ -61,4 +61,5 @@ struct MainMenuWidget: WidgetView {
6161
.navigationBar(title: "Menu", hidden: true)
6262
.safeArea(false)
6363
}
64+
6465
}

Sources/RxSwiftWidgets/Core/Widget.swift

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import UIKit
1111
/// Base type for any type of widget.
1212
public protocol AnyWidget { }
1313

14-
/// A special-purpose widget capable of building a specific UIViewController when asked.
14+
/// A special-purpose widget capable of building a specific UIViewController when asked. Does not generate UIViews.
1515
public protocol WidgetControllerType: AnyWidget {
1616
/// Builds or returns a UIViewController that wraps the current widget.
1717
func controller(with context: WidgetContext) -> UIViewController
@@ -44,11 +44,6 @@ public protocol WidgetsContaining: Widget {
4444
/// Common functions on WidgetViewType.
4545
extension WidgetViewType {
4646

47-
/// Allows any widget to be pushed or presented on the navigation stack.
48-
public func controller(with context: WidgetContext) -> UIViewController {
49-
return UIWidgetHostController(self, with: context)
50-
}
51-
5247
/// Walks widget tree of WidgetContaining and WidgetsContaining and calls closure on each node.
5348
public func walk(_ process: (_ widget: Widget) -> Void ) {
5449
func each(_ widget: Widget) {
@@ -64,3 +59,4 @@ extension WidgetViewType {
6459

6560
}
6661

62+
public struct WidgetFactory { }

Sources/RxSwiftWidgets/Core/WidgetNavigation.swift renamed to Sources/RxSwiftWidgets/Core/WidgetNavigator.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// WidgetNavigation.swift
2+
// WidgetNavigator.swift
33
// RxSwiftWidgets
44
//
55
// Created by Michael Long on 7/23/19.

Sources/RxSwiftWidgets/Core/WidgetView.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,25 @@ public protocol WidgetView: Widget {
1414

1515
func widget(_ context: WidgetContext) -> Widget
1616

17-
func onBuild(_ context: WidgetContext)
17+
func build(_ widget: Widget, with context: WidgetContext) -> UIView
1818

1919
}
2020

2121
extension WidgetView {
2222

23+
/// Hook for the standard build function. Delegates to build(:Widget:Context) function below.
2324
public func build(with context: WidgetContext) -> UIView {
24-
let widget = self.widget(context)
25+
return build(widget(context), with: context)
26+
}
27+
28+
/// Performs the actual widget build for WidgetView. Called by the standard build function.
29+
public func build(_ widget: Widget, with context: WidgetContext) -> UIView {
2530
let view = widget.build(with: context)
2631
if let modifying = self as? WidgetModifying {
2732
let context = modifying.modifiers.modified(context, for: view)
2833
modifying.modifiers.apply(to: view, with: context)
29-
onBuild(context)
30-
} else {
31-
onBuild(context.set(view: view))
3234
}
3335
return view
3436
}
3537

36-
public func onBuild(_ context: WidgetContext) { }
37-
3838
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
//
2+
// NavigationWidget.swift
3+
// RxSwiftWidgets
4+
//
5+
// Created by Michael Long on 9/16/19.
6+
//
7+
8+
import UIKit
9+
10+
/// Protocol indicates that current widget view should wraps its viewcontroller in a navigation controller.
11+
public protocol WidgetViewNavigating: WidgetView {
12+
13+
/// Returns a custom UINavigationController that's used to wrap the current widget's view controller.
14+
func navigationController(with context: WidgetContext) -> UINavigationController
15+
16+
}
17+
18+
extension WidgetFactory {
19+
20+
public static var defaultNavigationController: (_ context: WidgetContext) -> UINavigationController = { _ in
21+
return UINavigationController()
22+
}
23+
24+
}
25+
26+
extension WidgetViewNavigating {
27+
28+
/// Returns a custom UINavigationController that's used to wrap the current widget's view controller.
29+
///
30+
/// Default implementation returns a plain UINavigationController.
31+
///
32+
public func navigationController(with context: WidgetContext) -> UINavigationController {
33+
WidgetFactory.defaultNavigationController(context)
34+
}
35+
36+
}
37+
38+
extension WidgetViewType {
39+
40+
/// Allows any widget to be pushed or presented on the navigation stack. Calls the widget's build function and then
41+
/// wraps the result in an UIWidgetHostController.
42+
///
43+
/// If Self is WidgetViewNavigating then a UINavigationController is constructed and wrapped around the host controller.
44+
///
45+
public func controller(with context: WidgetContext) -> UIViewController {
46+
if let navigating = self as? WidgetViewNavigating {
47+
let navigationController = navigating.navigationController(with: context)
48+
let viewController = UIWidgetHostController(self, with: context)
49+
navigationController.addChild(viewController)
50+
return navigationController
51+
}
52+
return UIWidgetHostController(self, with: context)
53+
}
54+
55+
}

0 commit comments

Comments
 (0)