Skip to content

Commit d116925

Browse files
author
Michael Long
committed
Added Alert Widget and simplified push present calls
1 parent fb9cbad commit d116925

File tree

9 files changed

+97
-21
lines changed

9 files changed

+97
-21
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ struct UserListWidget: WidgetView {
7878
.accessoryType(.disclosureIndicator)
7979
}
8080
.onSelect { (context, path, user) in
81-
context.navigator?.push(widget: UserDetailsWidget(user: user))
81+
context.navigator?.push(UserDetailsWidget(user: user))
8282
context.tableView?.deselectRow(at: path, animated: true)
8383
}
8484
])
@@ -145,7 +145,7 @@ Note that while you can use a standard text-based table cell in RxSwiftWidgets,
145145

146146
```
147147
.onSelect { (context, path, user) in
148-
context.navigator?.push(widget: UserDetailsWidget(user: user))
148+
context.navigator?.push(UserDetailsWidget(user: user))
149149
context.tableView?.deselectRow(at: path, animated: true)
150150
}
151151
```

RxSwiftWidgets.xcodeproj/project.pbxproj

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
4CE3B6CA22F77EF000E47F57 /* ScrollWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE3B6C922F77EF000E47F57 /* ScrollWidget.swift */; };
7878
4CE3B6CC22F89F4300E47F57 /* DemoScrollingWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE3B6CB22F89F4300E47F57 /* DemoScrollingWidget.swift */; };
7979
4CE49AB922FCD7080030CD9D /* WidgetModifyUIControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE49AB822FCD7080030CD9D /* WidgetModifyUIControl.swift */; };
80+
4CF7B65C232EB609009484AE /* AlertWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF7B65B232EB609009484AE /* AlertWidget.swift */; };
8081
OBJ_341 /* BehaviorRelay+Driver.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_50 /* BehaviorRelay+Driver.swift */; };
8182
OBJ_342 /* Binder.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_51 /* Binder.swift */; };
8283
OBJ_343 /* ControlEvent+Driver.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_52 /* ControlEvent+Driver.swift */; };
@@ -603,6 +604,7 @@
603604
4CE3B6C922F77EF000E47F57 /* ScrollWidget.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScrollWidget.swift; sourceTree = "<group>"; };
604605
4CE3B6CB22F89F4300E47F57 /* DemoScrollingWidget.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = DemoScrollingWidget.swift; path = RxSwiftWidgetsDemo/Application/Features/DemoScrollingWidget.swift; sourceTree = SOURCE_ROOT; };
605606
4CE49AB822FCD7080030CD9D /* WidgetModifyUIControl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WidgetModifyUIControl.swift; sourceTree = "<group>"; };
607+
4CF7B65B232EB609009484AE /* AlertWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertWidget.swift; sourceTree = "<group>"; };
606608
OBJ_100 /* RxScrollViewDelegateProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RxScrollViewDelegateProxy.swift; sourceTree = "<group>"; };
607609
OBJ_101 /* RxSearchBarDelegateProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RxSearchBarDelegateProxy.swift; sourceTree = "<group>"; };
608610
OBJ_102 /* RxSearchControllerDelegateProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RxSearchControllerDelegateProxy.swift; sourceTree = "<group>"; };
@@ -1160,6 +1162,14 @@
11601162
path = Models;
11611163
sourceTree = "<group>";
11621164
};
1165+
4CF7B65A232EB5E0009484AE /* Navigation */ = {
1166+
isa = PBXGroup;
1167+
children = (
1168+
4CF7B65B232EB609009484AE /* AlertWidget.swift */,
1169+
);
1170+
path = Navigation;
1171+
sourceTree = "<group>";
1172+
};
11631173
OBJ_156 /* RxCocoaRuntime */ = {
11641174
isa = PBXGroup;
11651175
children = (
@@ -1399,8 +1409,9 @@
13991409
children = (
14001410
4C12006F23087520003B060C /* Containers */,
14011411
4C12007023087559003B060C /* Controls */,
1402-
4C120072230875B7003B060C /* TableView */,
1412+
4CF7B65A232EB5E0009484AE /* Navigation */,
14031413
4C1200712308758C003B060C /* General */,
1414+
4C120072230875B7003B060C /* TableView */,
14041415
);
14051416
path = Widgets;
14061417
sourceTree = "<group>";
@@ -2243,6 +2254,7 @@
22432254
OBJ_667 /* WidgetModifyUIViewLayer.swift in Sources */,
22442255
OBJ_668 /* WidgetModifyUIViewRx.swift in Sources */,
22452256
4CE3B6C522F77C3D00E47F57 /* TextFieldWidget.swift in Sources */,
2257+
4CF7B65C232EB609009484AE /* AlertWidget.swift in Sources */,
22462258
4C585DD822FB7BD7007E4F5F /* ObservableListBuilder.swift in Sources */,
22472259
4C120077230A15C6003B060C /* TableCellWidget.swift in Sources */,
22482260
4CE3B69E22F4BCBC00E47F57 /* WidgetAnimation.swift in Sources */,

RxSwiftWidgetsDemo/Application/Features/DemoDismissibleWidget.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ struct DemoDismissibleWidget: WidgetView {
3131
.numberOfLines(0)
3232
.padding(h: 0, v: 15),
3333

34-
ButtonWidget("Dismiss Returning Value")
34+
ButtonWidget("Return Random Number")
3535
.color(.orange)
3636
.onTap { context in
37-
context.navigator?.dismiss(returning: "Return Value")
37+
context.navigator?.dismiss(returning: "\(Int.random(in: 1..<1000))")
3838
},
3939

4040
ButtonWidget("Dismiss")

RxSwiftWidgetsDemo/Application/Features/FeaturesWidget.swift

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,25 +27,32 @@ struct FeaturesWidget: WidgetView {
2727
.padding(20),
2828

2929
MainMenuItemWidget(text: "Property Binding", onTap: { (context) in
30-
context.navigator?.push(widget: DemoBindingWidget(title: self.$title))
30+
context.navigator?.push(DemoBindingWidget(title: self.$title))
3131
}),
3232

3333
MainMenuItemWidget(text: "Dismissible", onTap: { context in
34-
context.navigator?.present(widget: DemoDismissibleWidget(), onDismiss: { (value: String) in
35-
print(value)
34+
context.navigator?.present(DemoDismissibleWidget(), onDismiss: { (value: String) in
35+
OperationQueue.main.addOperation {
36+
context.navigator?.present(
37+
AlertWidget(title: "Returned", message: value)
38+
.addAction(title: "Okay") { (context) in
39+
context.navigator?.dismiss()
40+
}
41+
)
42+
}
3643
})
3744
}),
3845

3946
MainMenuItemWidget(text: "Positioning", onTap: { context in
40-
context.navigator?.push(widget: DemoPositioningWidget())
47+
context.navigator?.push(DemoPositioningWidget())
4148
}),
4249

4350
MainMenuItemWidget(text: "Scrolling", onTap: { context in
44-
context.navigator?.push(widget: DemoScrollingWidget())
51+
context.navigator?.push(DemoScrollingWidget())
4552
}),
4653

4754
MainMenuItemWidget(text: "Static TableView", onTap: { context in
48-
context.navigator?.push(widget: DemoStaticTableViewWidget())
55+
context.navigator?.push(DemoStaticTableViewWidget())
4956
}),
5057

5158
ButtonWidget("Reset Title")

RxSwiftWidgetsDemo/Application/MainMenu/MainMenuWidget.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,19 @@ struct MainMenuWidget: WidgetView {
2828
),
2929

3030
MainMenuItemWidget(text: "Account Details", onTap: { context in
31-
context.navigator?.push(widget: AccountDetailsWidget())
31+
context.navigator?.push(AccountDetailsWidget())
3232
}),
3333

3434
MainMenuItemWidget(text: "Login Form", onTap: { context in
35-
context.navigator?.push(widget: LoginFormWidget())
35+
context.navigator?.push(LoginFormWidget())
3636
}),
3737

3838
MainMenuItemWidget(text: "User List", onTap: { context in
39-
context.navigator?.push(widget: UserListWidget())
39+
context.navigator?.push(UserListWidget())
4040
}),
4141

4242
MainMenuItemWidget(text: "Features", onTap: { context in
43-
context.navigator?.push(widget: FeaturesWidget())
43+
context.navigator?.push(FeaturesWidget())
4444
}),
4545

4646
]) // VStackWidget

RxSwiftWidgetsDemo/Application/Users/UserListWidget.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ struct UserListWidget: WidgetView {
3838
.accessoryType(.disclosureIndicator)
3939
}
4040
.onSelect { (context, path, user) in
41-
context.navigator?.push(widget: UserDetailsWidget(user: user))
41+
context.navigator?.push(UserDetailsWidget(user: user))
4242
context.tableView?.deselectRow(at: path, animated: true)
4343
}
4444
]) // TableWidget

Sources/RxSwiftWidgets/Core/WidgetDismissible.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ public struct WidgetDismissibleReturn<Value>: WidgetDismissibleType {
2222
}
2323

2424
public enum WidgetDismissiblePresentationType {
25+
case alert
2526
case presented
2627
case pushed
28+
case sheet
2729
}

Sources/RxSwiftWidgets/Core/WidgetNavigation.swift

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,35 +26,41 @@ public struct WidgetNavigator {
2626
// dismissible functionality
2727

2828
/// Pushes the widget onto the navigation stack in a new UIWidgetHostController.
29-
public func push(widget: Widget, animated: Bool = true) {
29+
public func push(_ widget: Widget, animated: Bool = true) {
3030
let context = self.context.set(presentation: .pushed)
3131
let viewController = UIWidgetHostController(widget, with: context)
3232
navigationController?.pushViewController(viewController, animated: animated)
3333
}
3434

3535
/// Pushes the widget onto the navigation stack in a new UIWidgetHostController with a return value handler.
36-
public func push<ReturnType>(widget: Widget, animated: Bool = true, onDismiss handler: @escaping WidgetDismissibleReturnHandler<ReturnType>) {
36+
public func push<ReturnType>(_ widget: Widget, animated: Bool = true, onDismiss handler: @escaping WidgetDismissibleReturnHandler<ReturnType>) {
3737
let context = self.context.set(presentation: .pushed)
3838
let dismissible = WidgetDismissibleReturn<ReturnType>(handler)
3939
let viewController = UIWidgetHostController(widget, with: context, dismissible: dismissible)
4040
navigationController?.pushViewController(viewController, animated: animated)
4141
}
4242

4343
/// Presents a widget on the navigation stack in a new UIWidgetHostController.
44-
public func present(widget: Widget, animated: Bool = true) {
44+
public func present(_ widget: Widget, animated: Bool = true) {
4545
let context = self.context.set(presentation: .presented)
4646
let viewController = UIWidgetHostController(widget, with: context)
4747
navigationController?.present(viewController, animated: animated, completion: nil)
4848
}
4949

5050
/// 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>) {
51+
public func present<ReturnType>(_ widget: Widget, animated: Bool = true, onDismiss handler: @escaping WidgetDismissibleReturnHandler<ReturnType>) {
5252
let context = self.context.set(presentation: .presented)
5353
let dismissible = WidgetDismissibleReturn<ReturnType>(handler)
5454
let viewController = UIWidgetHostController(widget, with: context, dismissible: dismissible)
5555
navigationController?.present(viewController, animated: animated, completion: nil)
5656
}
5757

58+
public func present(_ widget: WidgetController, animated: Bool = true) {
59+
let context = self.context.set(presentation: .alert)
60+
let viewController = widget.build(with: context)
61+
navigationController?.present(viewController, animated: animated, completion: nil)
62+
}
63+
5864
/// Pops or dismisses the current view controller, returning a value that will be passed to the onDismiss handler.
5965
public func dismiss<Value>(returning value: Value, animated: Bool = true) {
6066
if let dimissible = context.dismissible as? WidgetDismissibleReturn<Value> {
@@ -69,7 +75,7 @@ public struct WidgetNavigator {
6975
return
7076
}
7177
switch self.context.presentation {
72-
case .presented:
78+
case .alert, .presented, .sheet:
7379
viewController.dismiss(animated: animated, completion: nil)
7480
case .pushed:
7581
viewController.navigationController?.popToViewController(viewController, animated: false)
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
//
2+
// AlertWidget.swift
3+
// RxSwiftWidgets
4+
//
5+
// Created by Michael Long on 9/15/19.
6+
//
7+
8+
import UIKit
9+
10+
public protocol WidgetController {
11+
func build(with context: WidgetContext) -> UIViewController
12+
}
13+
14+
public struct AlertWidget: WidgetController {
15+
16+
internal let title: String?
17+
internal let message: String?
18+
19+
internal var actions: [WidgetAlertAction] = []
20+
21+
public init(title: String?, message: String?) {
22+
self.title = title
23+
self.message = message
24+
}
25+
26+
public func build(with context: WidgetContext) -> UIViewController {
27+
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
28+
let context = context.set(viewController: alert)
29+
for action in actions {
30+
alert.addAction(UIAlertAction(title: action.title, style: action.style, handler: { (_) in
31+
action.handler(context)
32+
}))
33+
}
34+
return alert
35+
}
36+
37+
public func addAction(title: String?, style: UIAlertAction.Style = .default, handler: @escaping (_ context: WidgetContext) -> Void) -> Self {
38+
var widget = self
39+
widget.actions.append(WidgetAlertAction(title: title, style: style, handler: handler))
40+
return widget
41+
}
42+
43+
}
44+
45+
internal struct WidgetAlertAction {
46+
let title: String?
47+
let style: UIAlertAction.Style
48+
let handler: (_ context: WidgetContext) -> Void
49+
}

0 commit comments

Comments
 (0)