Skip to content

Commit

Permalink
Add alert context and improve sheet context
Browse files Browse the repository at this point in the history
  • Loading branch information
danielsaidi committed Jun 7, 2020
1 parent 54de41c commit ad0c8b3
Show file tree
Hide file tree
Showing 31 changed files with 275 additions and 63 deletions.
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@

You can read more about the different parts of `SwiftUIKit` in separate readmes:

* [Blur][Blur]
* [Alerts][Alerts]
* [Blurs][Blurs]
* [Data][Data]
* [Extensions][Extensions]
* [Gestures][Gestures]
* [Sheets][Sheets]
* [Styles][Styles]
* [Toast][Toast]
* [Toasts][Toasts]

As things that exist in this library are added to `SwiftUI`, the corresponding functionality in this library will be deprecated and refer to those new features.

Expand Down Expand Up @@ -84,9 +86,11 @@ SwiftUIKit is available under the MIT license. See [LICENSE][License] file for m
[GitHub]: https://github.com/danielsaidi/SwiftUIKit
[License]: https://github.com/danielsaidi/SwiftUIKit/blob/master/LICENSE

[Blur]: Readmes/Blur.md
[Alerts]: Readmes/Alerts.md
[Blurs]: Readmes/Blurs.md
[Data]: Readmes/Data.md
[Extensions]: Readmes/Extensions.md
[Gestures]: Readmes/Gestures.md
[Sheets]: Readmes/Sheets.md
[Styles]: Readmes/Styles.md
[Toast]: Readmes/Toast.md
[Toasts]: Readmes/Toasts.md
12 changes: 12 additions & 0 deletions Readmes/Alerts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Alerts

`SwiftUIKit` makes it easier to work with alerts.


## AlertContext

The `AlertContext` class embeds the `isPresented` binding logic and can be used to present any `Alert` or `AlertPresentable`, which means that you can use it for a wide range of alerts and custom types within your apps.

You could for instance implement a global set of alerts in an `AppAlerts` enum or screen-specific screens in e.g. a `SettingsAlert` enum, and use the same `AlertContext` for all alerts.

Take a look at the demo app for an example on how to use this.
2 changes: 1 addition & 1 deletion Readmes/Blur.md → Readmes/Blurs.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Blur
# Blurs

`SwiftUIKit` contains additional blur logic, to make it possible to use the full range of `UIKit` blur effects in `SwiftUI`.

Expand Down
1 change: 0 additions & 1 deletion Readmes/Data.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ The `QrCodeGenerator` protocol can be implemented by anything that can generate
The `StandardQrCodeGenerator` implementation provides a standard way of doing this.



## UserDefaultsPersisted

The `UserDefaultsPersisted` property wrapper can be applied to any codable property to make it automatically sync with `UserDefaults`.
9 changes: 6 additions & 3 deletions Readmes/Sheets.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
# Sheets

`SwiftUIKit` makes managing modal sheets eaiser.
`SwiftUIKit` makes it easier to work with modal sheets.

The `SheetContext` class embeds the `isPresented` binding logic and can be used to present any `SheetPresentable`, which means that you can use it for a wide range of sheets.

You could for instance implement a global set of sheets in an `AppSheets` enum or screen-specific screens in e.g. a `SettingsEnum` enum, and use `SheetContext` for both.
## SheetContext

The `SheetContext` class embeds the `isPresented` binding logic and can be used to present any `SheetPresentable`, which means that you can use it for a wide range of sheets and custom types within your apps.

You could for instance implement a global set of sheets in an `AppSheets` enum or screen-specific screens in e.g. a `SettingsSheet` enum, and use the same `SheetContext` for all sheets.

Take a look at the demo app for an example on how to use this.
7 changes: 5 additions & 2 deletions Readmes/Toast.md → Readmes/Toasts.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Toast
# Toasts

`SwiftUIKit` contains logic for presenting a customizable toast message above another view.
`SwiftUIKit` contains logic for presenting customizable toast messages above another view.


## Toast

The `Toast` view has custom `content` and `background` views, which means that you can present anything in this toast.

Expand Down
3 changes: 2 additions & 1 deletion Release Notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

This release adds:

* A `SheetContext` that simplifies working with action sheets.
* An `AlertContext` that simplifies working with alerts.
* A `SheetContext` that simplifies working with modal sheets.
* A `QrCodeGenerator` and a `StandardQrCodeGenerator` implementation.


Expand Down
51 changes: 51 additions & 0 deletions Sources/SwiftUIKit/Alerts/AlertContext.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//
// AlertContext.swift
// SwiftUIKit
//
// Created by Daniel Saidi on 2020-06-07.
// Copyright © 2020 Daniel Saidi. All rights reserved.
//

import Combine
import SwiftUI

/**
This context can be used to present any `Alert`, as well as
anything that implements`AlertPresentable`.

`AlertPresentable` can be implemented by any enum, class or
struct that can provide an `alert` to the context. It means
that you can implement custom alerts in many different ways
and present all of them the same way, using this context.

To use this context within your view, create an instance of
it then call any of the `present(_ alert: AlertPresentable)`
or `present(_ alert: Alert)` to present alerts. To bind the
alert to views, use the `alert` modifier as you normally do:

```swift
.alert(isPresented: $alertContext.isActive, content: alertContext.alert)
```
*/
public class AlertContext: ObservableObject {

public init() {}

@Published public var isActive = false

public private(set) var alertView: Alert? {
didSet { isActive = alertView != nil }
}

public func alert() -> Alert {
alertView ?? Alert(title: Text(""))
}

public func present(_ alert: Alert) {
alertView = alert
}

public func present(_ alert: AlertPresentable) {
alertView = alert.alert
}
}
18 changes: 18 additions & 0 deletions Sources/SwiftUIKit/Alerts/AlertPresentable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// AlertPresentable.swift
// SwiftUIKit
//
// Created by Daniel Saidi on 2020-06-07.
// Copyright © 2020 Daniel Saidi. All rights reserved.
//

import SwiftUI

/**
This protocol can be implemented by anything (e.g. a custom
enum, struct or a class) that can provide an alert.
*/
public protocol AlertPresentable {

var alert: Alert { get }
}
File renamed without changes.
File renamed without changes.
41 changes: 21 additions & 20 deletions Sources/SwiftUIKit/Sheets/SheetContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,22 @@ import Combine
import SwiftUI

/**
This context can be used to manage action sheets, so a view
can present a wide range of sheets with a single modifier.
This context can be used to present any `View` and anything
that implements`SheetPresentable` as modal sheets.

`SheetPresentable` can be implemented by any types that can
provide a view to this context. It could for instance be an
app-wide or view-specific enum...or both. This means that a
view can display a bunch of sheets in the same way.
`SheetPresentable` can be implemented by any enum, class or
struct that can provide a `sheet` to this context. It means
that you can implement custom sheets in many different ways
and present all of them the same way, using this context.

To use this context within your view, create an instance of
it and set its `sheet` property whenever you want to show a
sheet. You can also use `present(_ sheet: SheetPresentable)`
which just sets the sheet property.

To bind the sheet to your view, you can just use the `sheet`
modifier as you would do with any other sheet:
it then call any of the `present(_ sheet: SheetPresentable)`
or `present<Sheet: View>(_ sheet: Sheet)` to present sheets.
To bind the sheet to views, use the `sheet` modifier as you
normally do:

```swift
.sheet(isPresented: $sheetContext.isActive, content: sheetContext.view)
.sheet(isPresented: $sheetContext.isActive, content: sheetContext.sheet)
```
*/
public class SheetContext: ObservableObject {
Expand All @@ -36,16 +34,19 @@ public class SheetContext: ObservableObject {

@Published public var isActive = false

public var sheet: SheetPresentable? {
didSet { isActive = sheet != nil }
public private(set) var sheetView: AnyView? {
didSet { isActive = sheetView != nil }
}

public func view() -> AnyView {
if let view = sheet?.sheetView { return view.any() }
return EmptyView().any()
public func present(_ sheet: SheetPresentable) {
sheetView = sheet.sheet
}

public func present(_ sheet: SheetPresentable) {
self.sheet = sheet
public func present<Sheet: View>(_ sheet: Sheet) {
sheetView = sheet.any()
}

public func sheet() -> AnyView {
sheetView?.any() ?? EmptyView().any()
}
}
7 changes: 4 additions & 3 deletions Sources/SwiftUIKit/Sheets/SheetPresentable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@
import SwiftUI

/**
This protocol can be implemented by any type (e.g. an enum)
that can provide a view to be displayed in a modal sheet.
This protocol can be implemented by anything (e.g. a custom
enum, struct or a class) that can provide views that should
be presented as modal sheets.
*/
public protocol SheetPresentable {

var sheetView: AnyView { get }
var sheet: AnyView { get }
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit ad0c8b3

Please sign in to comment.