9
9
import UIKit
10
10
import RxSwift
11
11
12
-
12
+ /// WidgetNavigator provides access to the current UINavgiationController and navigation stack.
13
13
public struct WidgetNavigator {
14
14
15
15
var context : WidgetContext
@@ -18,54 +18,88 @@ public struct WidgetNavigator {
18
18
self . context = context
19
19
}
20
20
21
+ /// Returns the current UINavigation controller for the current context.
21
22
public var navigationController : UINavigationController ? {
22
23
context. viewController? . navigationController
23
24
}
24
25
25
26
// dismissible functionality
26
27
28
+ /// Pushes the widget onto the navigation stack in a new UIWidgetHostController.
27
29
public func push( widget: Widget , animated: Bool = true ) {
30
+ let context = self . context. set ( presentation: . pushed)
28
31
let viewController = UIWidgetHostController ( widget, with: context)
29
32
navigationController? . pushViewController ( viewController, animated: animated)
30
33
}
31
34
35
+ /// Pushes the widget onto the navigation stack in a new UIWidgetHostController with a return value handler.
32
36
public func push< ReturnType> ( widget: Widget , animated: Bool = true , onDismiss handler: @escaping WidgetDismissibleReturnHandler < ReturnType > ) {
37
+ let context = self . context. set ( presentation: . pushed)
33
38
let dismissible = WidgetDismissibleReturn < ReturnType > ( handler)
34
39
let viewController = UIWidgetHostController ( widget, with: context, dismissible: dismissible)
35
40
navigationController? . pushViewController ( viewController, animated: animated)
36
41
}
37
42
43
+ /// Presents a widget on the navigation stack in a new UIWidgetHostController.
44
+ public func present( widget: Widget , animated: Bool = true ) {
45
+ let context = self . context. set ( presentation: . presented)
46
+ let viewController = UIWidgetHostController ( widget, with: context)
47
+ navigationController? . present ( viewController, animated: animated, completion: nil )
48
+ }
49
+
50
+ /// Presents a widget on the navigation stack in a new UIWidgetHostController with a return value handler.
51
+ public func present< ReturnType> ( widget: Widget , animated: Bool = true , onDismiss handler: @escaping WidgetDismissibleReturnHandler < ReturnType > ) {
52
+ let context = self . context. set ( presentation: . presented)
53
+ let dismissible = WidgetDismissibleReturn < ReturnType > ( handler)
54
+ let viewController = UIWidgetHostController ( widget, with: context, dismissible: dismissible)
55
+ navigationController? . present ( viewController, animated: animated, completion: nil )
56
+ }
57
+
58
+ /// Pops or dismisses the current view controller, returning a value that will be passed to the onDismiss handler.
38
59
public func dismiss< Value> ( returning value: Value , animated: Bool = true ) {
39
60
if let dimissible = context. dismissible as? WidgetDismissibleReturn < Value > {
40
61
dimissible. handler ( value)
41
62
}
42
63
dismiss ( animated: animated)
43
64
}
44
65
66
+ /// Pops or dismisses the current view controller, dependent upon the presentation state.
45
67
public func dismiss( animated: Bool = true ) {
46
- guard let viewController = context. viewController else { return }
47
- viewController. navigationController? . popToViewController ( viewController, animated: false )
48
- viewController. navigationController? . popViewController ( animated: animated)
68
+ guard let viewController = context. viewController else {
69
+ return
70
+ }
71
+ switch self . context. presentation {
72
+ case . presented:
73
+ viewController. dismiss ( animated: animated, completion: nil )
74
+ case . pushed:
75
+ viewController. navigationController? . popToViewController ( viewController, animated: false )
76
+ viewController. navigationController? . popViewController ( animated: animated)
77
+ }
49
78
}
50
79
51
80
// standard functionality
52
81
82
+ /// Pushes a non-widget baseed view controller onto the current navigation stack.
53
83
public func pushViewController( _ viewController: UIViewController , animated: Bool = true ) {
54
84
navigationController? . pushViewController ( viewController, animated: animated)
55
85
}
56
86
87
+ /// Pops a view controller from the current navigation stack.
57
88
public func popViewController( animated: Bool = true ) {
58
89
navigationController? . popViewController ( animated: animated)
59
90
}
60
91
92
+ /// Pops to the root view controller on the current navigation stack.
61
93
public func popToRootViewController( animated: Bool = true ) {
62
94
navigationController? . popToRootViewController ( animated: animated)
63
95
}
64
96
97
+ /// Presents a view controller using the current navigation stack.
65
98
public func presentViewController( _ viewController: UIViewController , animated: Bool = true ) {
66
99
context. viewController? . present ( viewController, animated: animated, completion: nil )
67
100
}
68
101
102
+ /// Dismisses a view controller from the current navigation stack.
69
103
public func dismissViewController( animated: Bool = true ) {
70
104
context. viewController? . dismiss ( animated: animated, completion: nil )
71
105
}
@@ -75,36 +109,51 @@ public struct WidgetNavigator {
75
109
76
110
extension WidgetContext {
77
111
112
+ /// Returns the Navigator for the current context.
78
113
public var navigator : WidgetNavigator ? {
79
114
if viewController != nil {
80
115
return WidgetNavigator ( self )
81
116
}
82
117
return nil
83
118
}
84
119
120
+ /// Returns the current context with a new RxSwift DisposeBag for subscriptions.
85
121
public func new( ) -> WidgetContext {
86
122
var context = self
87
123
context. disposeBag = DisposeBag ( )
88
124
return context
89
125
}
90
126
127
+ /// Sets the current view controller to be the passed view controller.
91
128
public func set( viewController: UIViewController ) -> WidgetContext {
92
129
var context = self
93
130
context. viewController = viewController
94
131
return context
95
132
}
96
133
134
+ /// Returns the current navigation dismissible, if any.
97
135
public var dismissible : WidgetDismissibleType ? {
98
136
return get ( WidgetDismissibleType . self)
99
137
}
100
138
139
+ /// Sets the current navigation dismissible.
101
140
public func set( dismissible: WidgetDismissibleType ? ) -> WidgetContext {
102
141
if let dismissible = dismissible {
103
142
return put ( dismissible)
104
143
}
105
144
return self
106
145
}
107
146
147
+ /// Returns the current navigation presentation type for the current view controller.
148
+ public var presentation : WidgetDismissiblePresentationType {
149
+ return find ( WidgetDismissiblePresentationType . self) ?? . pushed
150
+ }
151
+
152
+ /// Sets the current navigation presentation type for the current view controller.
153
+ public func set( presentation: WidgetDismissiblePresentationType ) -> WidgetContext {
154
+ return put ( presentation)
155
+ }
156
+
108
157
}
109
158
110
159
fileprivate struct UIViewControllerBox {
0 commit comments