Skip to content

Commit 6691d21

Browse files
committed
Add more intro screen styles
1 parent 7e094e9 commit 6691d21

11 files changed

+328
-210
lines changed

RELEASE_NOTES.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,17 @@ These release notes only cover the current major version.
1313

1414

1515

16+
## 9.1.2
17+
18+
This version fixes a localization bug.
19+
20+
### ✨ Features
21+
22+
* `OnboardingIntroScreenStyle` has new styles.
23+
* `OnboardingUsp` has new `iconView` and `image` builders.
24+
25+
26+
1627
## 9.1.1
1728

1829
This version fixes a localization bug.

Sources/OnboardingKit/OnboardingUsp.swift

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import SwiftUI
1212
/// This model represents a unique selling point in an oboarding context.
1313
public struct OnboardingUsp<Icon: View> {
1414

15-
/// Create a USP value.
15+
/// Create a USP value with a custom icon.
1616
///
1717
/// - Parameters:
1818
/// - title: An optional localized USP title.
@@ -29,7 +29,24 @@ public struct OnboardingUsp<Icon: View> {
2929
self.image = nil
3030
}
3131

32-
/// Create a USP value.
32+
/// Create a USP value with a custom icon.
33+
///
34+
/// - Parameters:
35+
/// - title: An optional localized USP title.
36+
/// - text: A localized USP text.
37+
/// - icon: A USP icon view builder.
38+
public init(
39+
title: LocalizedStringKey? = nil,
40+
text: LocalizedStringKey,
41+
@ViewBuilder icon: @escaping () -> Icon
42+
) {
43+
self.title = title
44+
self.text = text
45+
self.icon = icon()
46+
self.image = nil
47+
}
48+
49+
/// Create an image-based USP value.
3350
///
3451
/// - Parameters:
3552
/// - title: An optional localized USP title.
@@ -58,3 +75,51 @@ public struct OnboardingUsp<Icon: View> {
5875
/// An optional USP icon image.
5976
public let image: Image?
6077
}
78+
79+
public extension OnboardingUsp {
80+
81+
/// Create an image-based USP value.
82+
///
83+
/// - Parameters:
84+
/// - title: An optional localized USP title.
85+
/// - text: A localized USP text.
86+
/// - image: A USP icon image.
87+
static func iconView(
88+
title: LocalizedStringKey? = nil,
89+
text: LocalizedStringKey,
90+
icon: Icon
91+
) -> Self {
92+
self.init(title: title, text: text, icon: icon)
93+
}
94+
95+
/// Create an image-based USP value.
96+
///
97+
/// - Parameters:
98+
/// - title: An optional localized USP title.
99+
/// - text: A localized USP text.
100+
/// - image: A USP icon image builder.
101+
static func iconView(
102+
title: LocalizedStringKey? = nil,
103+
text: LocalizedStringKey,
104+
@ViewBuilder icon: @escaping () -> Icon
105+
) -> Self {
106+
self.init(title: title, text: text, icon: icon)
107+
}
108+
}
109+
110+
public extension OnboardingUsp where Icon == Image {
111+
112+
/// Create an image-based USP value.
113+
///
114+
/// - Parameters:
115+
/// - title: An optional localized USP title.
116+
/// - text: A localized USP text.
117+
/// - image: A USP icon image.
118+
static func image(
119+
title: LocalizedStringKey? = nil,
120+
text: LocalizedStringKey,
121+
image: Image
122+
) -> Self {
123+
self.init(title: title, text: text, image: image)
124+
}
125+
}

Sources/OnboardingKit/Views/OnboardingIntroScreen.swift

Lines changed: 71 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,17 @@
88

99
import SwiftUI
1010

11-
/// This screen can be used as an intro screen when onboarding new users.
11+
// MARK: - View
12+
13+
/// This screen can be used to onboard new users.
1214
///
13-
/// This screen can be used to welcome users, show a summary of what the app
14-
/// does, and list high-level USPs.
15+
/// This screen can be used to welcome users, show a summary
16+
/// of what the app does, and list high-level USPs.
1517
///
16-
/// This view can be styled with``SwiftUICore/View/onboardingIntroScreenStyle(_:)`.
18+
/// This view can be styled with ``SwiftUICore/View/onboardingIntroScreenStyle(_:)``
19+
/// and uses views that can be styled using their own styles,
20+
/// like ``SwiftUICore/View/onboardingUspListStyle(_:)`` and
21+
/// ``SwiftUICore/View/onboardingUspListItemStyle(_:)``.
1722
public struct OnboardingIntroScreen<UspIcon: View>: View {
1823

1924
public init(
@@ -66,7 +71,7 @@ public struct OnboardingIntroScreen<UspIcon: View>: View {
6671
@Environment(\.onboardingIntroScreenStyle) var style
6772

6873
public var body: some View {
69-
VStack(spacing: 45) {
74+
VStack(spacing: style.sectionSpacing) {
7075
titleStack
7176
text(text)
7277
.discrete()
@@ -87,7 +92,7 @@ private extension OnboardingIntroScreen {
8792
}
8893

8994
var titleStack: some View {
90-
VStack(spacing: 25) {
95+
VStack(spacing: style.titleSpacing) {
9196
icon
9297
.resizable()
9398
.aspectRatio(contentMode: .fit)
@@ -114,6 +119,53 @@ extension View {
114119
}
115120
}
116121

122+
123+
// MARK: - Style
124+
125+
/// This style can be used with ``OnboardingIntroScreen``.
126+
///
127+
/// This style can be applied with``SwiftUICore/View/onboardingIntroScreenStyle(_:)`.
128+
public struct OnboardingIntroScreenStyle {
129+
130+
public init(
131+
iconSize: Double = 100,
132+
titleSpacing: Double = 25,
133+
sectionSpacing: Double = 45
134+
) {
135+
self.iconSize = iconSize
136+
self.titleSpacing = titleSpacing
137+
self.sectionSpacing = sectionSpacing
138+
}
139+
140+
public let iconSize: Double
141+
public let titleSpacing: Double
142+
public let sectionSpacing: Double
143+
}
144+
145+
public extension OnboardingIntroScreenStyle {
146+
147+
/// The standard intro screen style.
148+
static var standard: Self { .init() }
149+
}
150+
151+
public extension EnvironmentValues {
152+
153+
@Entry var onboardingIntroScreenStyle = OnboardingIntroScreenStyle()
154+
}
155+
156+
public extension View {
157+
158+
func onboardingIntroScreenStyle(
159+
_ style: OnboardingIntroScreenStyle
160+
) -> some View {
161+
self.environment(\.onboardingIntroScreenStyle, style)
162+
}
163+
}
164+
165+
166+
167+
// MARK: - Preview
168+
117169
#Preview {
118170

119171
ScrollView(.vertical) {
@@ -127,33 +179,40 @@ extension View {
127179
.init(
128180
title: "Onboarding",
129181
text: "Design great onboardings with various **onboarding types**.",
130-
icon: .init(systemName: "lightbulb")
182+
image: .init(systemName: "lightbulb")
131183
),
132184
.init(
133185
title: "Flows",
134186
text: "Sophisticated **page views** and **slideshows**.",
135-
icon: .init(systemName: "appwindow.swipe.rectangle")
187+
image: .init(systemName: "appwindow.swipe.rectangle")
136188
),
137189
.init(
138190
title: "Views",
139191
text: "Reduce implementation time with screen templates, buttons, etc.",
140-
icon: .init(systemName: "square")
192+
image: .init(systemName: "square")
141193
),
142194
.init(
143195
title: "Flows",
144196
text: "Sophisticated **page views** and **slideshows**.",
145-
icon: .init(systemName: "appwindow.swipe.rectangle")
197+
image: .init(systemName: "appwindow.swipe.rectangle")
146198
),
147199
.init(
148200
title: "Views",
149201
text: "Reduce implementation time with screen templates, buttons, etc.",
150-
icon: .init(systemName: "square")
202+
image: .init(systemName: "square")
151203
)
152204
]
153205
)
154206
}
155207
}
156208
.onboardingIntroScreenStyle(.init(
157-
uspListPresentationDelay: 0.1
209+
iconSize: 30,
210+
sectionSpacing: 35
211+
))
212+
.onboardingUspListStyle(.init(
213+
itemSpacing: 15
214+
))
215+
.onboardingUspListItemStyle(.init(
216+
iconSize: 30
158217
))
159218
}

Sources/OnboardingKit/Views/OnboardingIntroScreenStyle.swift

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -8,48 +8,3 @@
88

99
import SwiftUI
1010

11-
/// This style can be used with ``OnboardingIntroScreen``.
12-
///
13-
/// This style can be applied with``SwiftUICore/View/onboardingIntroScreenStyle(_:)`.
14-
public struct OnboardingIntroScreenStyle {
15-
16-
public init(
17-
iconSize: Double = 100,
18-
uspListPadding: Double = 0,
19-
uspListPresentationDuration: Double = 0.5,
20-
uspListPresentationDelay: Double = 0.2,
21-
uspListSpacing: Double = 30
22-
) {
23-
self.iconSize = iconSize
24-
self.uspListPadding = uspListPadding
25-
self.uspListPresentationDuration = uspListPresentationDuration
26-
self.uspListPresentationDelay = uspListPresentationDelay
27-
self.uspListSpacing = uspListSpacing
28-
}
29-
30-
public let iconSize: Double
31-
public let uspListPadding: Double
32-
public let uspListPresentationDuration: Double
33-
public let uspListPresentationDelay: Double
34-
public let uspListSpacing: Double
35-
}
36-
37-
public extension OnboardingIntroScreenStyle {
38-
39-
/// The standard intro screen style.
40-
static var standard: Self { .init() }
41-
}
42-
43-
public extension EnvironmentValues {
44-
45-
@Entry var onboardingIntroScreenStyle = OnboardingIntroScreenStyle()
46-
}
47-
48-
public extension View {
49-
50-
func onboardingIntroScreenStyle(
51-
_ style: OnboardingIntroScreenStyle
52-
) -> some View {
53-
self.environment(\.onboardingIntroScreenStyle, style)
54-
}
55-
}

Sources/OnboardingKit/Views/OnboardingPageView.swift

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ import SwiftUI
1212
import PageView
1313
#endif
1414

15+
16+
// MARK: - View
17+
1518
/// This view can be used to show a collection of onboarding pages, with support
1619
/// for navigating with swipes, arrow keys, and edge taps.
1720
///
@@ -102,6 +105,59 @@ private extension OnboardingPageView {
102105
}
103106
}
104107

108+
109+
// MARK: - Style
110+
111+
/// This style can style ``OnboardingPageView`` views.
112+
///
113+
/// This style can be applied with ``SwiftUICore/View/onboardingPageViewStyle(_:)``.
114+
public struct OnboardingPageViewStyle {
115+
116+
/// Create an onboarding page view style.
117+
///
118+
/// - Parameters:
119+
/// - pageIndicatorTintColor: The page indicator color to use, by default `.primary` with `0.3` opacity.
120+
/// - currentPageIndicatorTintColor: The color of the current page indicator, by default `.primary`.
121+
public init(
122+
pageIndicatorTintColor: Color = .primary.opacity(0.3),
123+
currentPageIndicatorTintColor: Color = .primary
124+
) {
125+
self.pageIndicatorTintColor = pageIndicatorTintColor
126+
self.currentPageIndicatorTintColor = currentPageIndicatorTintColor
127+
}
128+
129+
/// The page indicator color to use.
130+
public var pageIndicatorTintColor: Color
131+
132+
/// The color of the current page indicator.
133+
public var currentPageIndicatorTintColor: Color
134+
}
135+
136+
public extension OnboardingPageViewStyle {
137+
138+
/// A standard onboarding page view style.
139+
static var standard: Self { .init() }
140+
}
141+
142+
public extension View {
143+
144+
/// Apply a page view style environment value.
145+
func onboardingPageViewStyle(
146+
_ style: OnboardingPageViewStyle
147+
) -> some View {
148+
self.environment(\.onboardingPageViewStyle, style)
149+
}
150+
}
151+
152+
public extension EnvironmentValues {
153+
154+
/// An onboarding page view style value.
155+
@Entry var onboardingPageViewStyle = OnboardingPageViewStyle.standard
156+
}
157+
158+
159+
// MARK: - Preview
160+
105161
#Preview {
106162

107163
struct Preview: View {

0 commit comments

Comments
 (0)