Skip to content

Commit 1df9cf9

Browse files
committed
Add toolbar components
1 parent d80fbda commit 1df9cf9

File tree

8 files changed

+781
-0
lines changed

8 files changed

+781
-0
lines changed
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
//
2+
// Software Name: OUDS iOS
3+
// SPDX-FileCopyrightText: Copyright (c) Orange SA
4+
// SPDX-License-Identifier: MIT
5+
//
6+
// This software is distributed under the MIT license,
7+
// the text of which is available at https://opensource.org/license/MIT/
8+
// or see the "LICENSE" file for more details.
9+
//
10+
// Authors: See CONTRIBUTORS.txt
11+
// Software description: A SwiftUI components library with code examples for Orange Unified Design System
12+
//
13+
14+
import OUDSThemesContract
15+
import SwiftUI
16+
17+
#if canImport(UIKit)
18+
import UIKit
19+
#endif
20+
21+
@available(iOS 15, macOS 15, visionOS 1, *)
22+
struct ToolBarBottomAppearanceModifier: ViewModifier {
23+
24+
@Environment(\.theme) private var theme
25+
@Environment(\.colorScheme) private var colorScheme
26+
27+
func body(content: Content) -> some View {
28+
content
29+
.onAppear {
30+
setupToolBarAppearance()
31+
}
32+
#if os(iOS)
33+
.onChange(of: colorScheme) { newColorScheme in
34+
setupToolBarAppearance(withColor: newColorScheme)
35+
}
36+
.onChange(of: theme) { newTheme in
37+
setupToolBarAppearance(withTheme: newTheme)
38+
}
39+
#endif
40+
#if os(visionOS)
41+
// Conflict between SwiftLint and SwiftFormat
42+
// swiftlint:disable closure_end_indentation
43+
.onChange(of: colorScheme) { _, newColorScheme in
44+
setupToolBarAppearance(withColor: newColorScheme)
45+
}
46+
.onChange(of: theme) { _, newTheme in
47+
setupToolBarAppearance(withTheme: newTheme)
48+
}
49+
// swiftlint:enable closure_end_indentation
50+
#endif
51+
}
52+
53+
private func setupToolBarAppearance(withColor scheme: ColorScheme? = nil,
54+
withTheme theme: OUDSTheme? = nil)
55+
{
56+
#if os(iOS)
57+
if #available(iOS 26.0, *) {
58+
return
59+
}
60+
61+
let schemeToApply = scheme ?? colorScheme
62+
let themeToApply = theme ?? self.theme
63+
let appearance = UIToolbarAppearance()
64+
65+
appearance.configureWithTransparentBackground()
66+
appearance.backgroundEffect = UIBlurEffect(style: .regular)
67+
appearance.backgroundColor = themeToApply.bar.colorBgTranslucent.color(for: schemeToApply).uiColor
68+
69+
let toolBar = UIToolbar.appearance()
70+
toolBar.standardAppearance = appearance
71+
toolBar.scrollEdgeAppearance = appearance
72+
73+
DispatchQueue.main.async {
74+
updateExistingToolBars(with: appearance)
75+
}
76+
#endif
77+
}
78+
79+
#if os(iOS)
80+
private func updateExistingToolBars(with appearance: UIToolbarAppearance) {
81+
guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene else { return }
82+
83+
for window in windowScene.windows {
84+
updateToolBars(in: window.rootViewController, with: appearance)
85+
}
86+
}
87+
88+
private func updateToolBars(in viewController: UIViewController?, with appearance: UIToolbarAppearance) {
89+
guard let viewController else { return }
90+
91+
if let navigationController = viewController as? UINavigationController {
92+
navigationController.toolbar.standardAppearance = appearance
93+
navigationController.toolbar.scrollEdgeAppearance = appearance
94+
95+
navigationController.toolbar.setNeedsLayout()
96+
navigationController.toolbar.layoutIfNeeded()
97+
}
98+
99+
for child in viewController.children {
100+
updateToolBars(in: child, with: appearance)
101+
}
102+
103+
if let presented = viewController.presentedViewController {
104+
updateToolBars(in: presented, with: appearance)
105+
}
106+
}
107+
#endif
108+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//
2+
// Software Name: OUDS iOS
3+
// SPDX-FileCopyrightText: Copyright (c) Orange SA
4+
// SPDX-License-Identifier: MIT
5+
//
6+
// This software is distributed under the MIT license,
7+
// the text of which is available at https://opensource.org/license/MIT/
8+
// or see the "LICENSE" file for more details.
9+
//
10+
// Authors: See CONTRIBUTORS.txt
11+
// Software description: A SwiftUI components library with code examples for Orange Unified Design System
12+
//
13+
14+
import OUDSThemesContract
15+
import SwiftUI
16+
17+
@available(iOS 15, macOS 15, visionOS 1, *)
18+
struct ToolBarItemStyleModifier: ViewModifier {
19+
20+
let placement: OUDSToolBarItemPlacement
21+
22+
@Environment(\.theme) private var theme
23+
24+
@ViewBuilder
25+
func body(content: Content) -> some View {
26+
switch placement {
27+
case .leading:
28+
content
29+
.oudsForegroundColor(theme.colors.contentDefault)
30+
case .trailing:
31+
trailingItem(content: content)
32+
}
33+
}
34+
35+
@ViewBuilder
36+
private func trailingItem(content: Content) -> some View {
37+
#if os(iOS)
38+
if #available(iOS 26.0, *) {
39+
content
40+
.oudsForegroundColor(theme.colors.contentDefault)
41+
.oudsBackground(theme.colors.actionAccent)
42+
} else {
43+
content
44+
.oudsForegroundColor(theme.colors.contentDefault)
45+
}
46+
#else
47+
content
48+
.oudsForegroundColor(theme.colors.contentDefault)
49+
#endif
50+
}
51+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//
2+
// Software Name: OUDS iOS
3+
// SPDX-FileCopyrightText: Copyright (c) Orange SA
4+
// SPDX-License-Identifier: MIT
5+
//
6+
// This software is distributed under the MIT license,
7+
// the text of which is available at https://opensource.org/license/MIT/
8+
// or see the "LICENSE" file for more details.
9+
//
10+
// Authors: See CONTRIBUTORS.txt
11+
// Software description: A SwiftUI components library with code examples for Orange Unified Design System
12+
//
13+
14+
import OUDSThemesContract
15+
import SwiftUI
16+
17+
@available(iOS 15, macOS 15, visionOS 1, *)
18+
struct ToolBarTitleView: View {
19+
20+
let title: String
21+
let subtitle: String?
22+
23+
@Environment(\.theme) private var theme
24+
25+
var body: some View {
26+
VStack(spacing: 0) {
27+
Text(LocalizedStringKey(title))
28+
.headingSmall(theme)
29+
.oudsForegroundColor(theme.colors.contentDefault)
30+
31+
if let subtitle {
32+
Text(LocalizedStringKey(subtitle))
33+
.bodyDefaultSmall(theme)
34+
.oudsForegroundColor(theme.colors.contentDefault)
35+
}
36+
}
37+
.multilineTextAlignment(.center)
38+
}
39+
}
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
//
2+
// Software Name: OUDS iOS
3+
// SPDX-FileCopyrightText: Copyright (c) Orange SA
4+
// SPDX-License-Identifier: MIT
5+
//
6+
// This software is distributed under the MIT license,
7+
// the text of which is available at https://opensource.org/license/MIT/
8+
// or see the "LICENSE" file for more details.
9+
//
10+
// Authors: See CONTRIBUTORS.txt
11+
// Software description: A SwiftUI components library with code examples for Orange Unified Design System
12+
//
13+
14+
import OUDSThemesContract
15+
import SwiftUI
16+
17+
#if canImport(UIKit)
18+
import UIKit
19+
#endif
20+
21+
@available(iOS 15, macOS 15, visionOS 1, *)
22+
struct ToolBarTopAppearanceModifier: ViewModifier {
23+
24+
@Environment(\.theme) private var theme
25+
@Environment(\.colorScheme) private var colorScheme
26+
27+
func body(content: Content) -> some View {
28+
content
29+
.onAppear {
30+
setupNavigationBarAppearance()
31+
}
32+
#if os(iOS)
33+
.onChange(of: colorScheme) { newColorScheme in
34+
setupNavigationBarAppearance(withColor: newColorScheme)
35+
}
36+
.onChange(of: theme) { newTheme in
37+
setupNavigationBarAppearance(withTheme: newTheme)
38+
}
39+
#endif
40+
#if os(visionOS)
41+
// Conflict between SwiftLint and SwiftFormat
42+
// swiftlint:disable closure_end_indentation
43+
.onChange(of: colorScheme) { _, newColorScheme in
44+
setupNavigationBarAppearance(withColor: newColorScheme)
45+
}
46+
.onChange(of: theme) { _, newTheme in
47+
setupNavigationBarAppearance(withTheme: newTheme)
48+
}
49+
// swiftlint:enable closure_end_indentation
50+
#endif
51+
}
52+
53+
private func setupNavigationBarAppearance(withColor scheme: ColorScheme? = nil,
54+
withTheme theme: OUDSTheme? = nil)
55+
{
56+
#if os(iOS)
57+
if #available(iOS 26.0, *) {
58+
return
59+
}
60+
61+
let schemeToApply = scheme ?? colorScheme
62+
let themeToApply = theme ?? self.theme
63+
let appearance = UINavigationBarAppearance()
64+
65+
appearance.configureWithTransparentBackground()
66+
appearance.backgroundEffect = UIBlurEffect(style: .regular)
67+
appearance.backgroundColor = themeToApply.bar.colorBgTranslucent.color(for: schemeToApply).uiColor
68+
69+
let titleColor = themeToApply.colors.contentDefault.color(for: schemeToApply).uiColor
70+
appearance.titleTextAttributes = [.foregroundColor: titleColor]
71+
appearance.largeTitleTextAttributes = [.foregroundColor: titleColor]
72+
73+
let navigationBar = UINavigationBar.appearance()
74+
navigationBar.standardAppearance = appearance
75+
navigationBar.scrollEdgeAppearance = appearance
76+
navigationBar.compactAppearance = appearance
77+
78+
DispatchQueue.main.async {
79+
updateExistingNavigationBars(with: appearance)
80+
}
81+
#endif
82+
}
83+
84+
#if os(iOS)
85+
private func updateExistingNavigationBars(with appearance: UINavigationBarAppearance) {
86+
guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene else { return }
87+
88+
for window in windowScene.windows {
89+
updateNavigationBars(in: window.rootViewController, with: appearance)
90+
}
91+
}
92+
93+
private func updateNavigationBars(in viewController: UIViewController?, with appearance: UINavigationBarAppearance) {
94+
guard let viewController else { return }
95+
96+
if let navigationController = viewController as? UINavigationController {
97+
navigationController.navigationBar.standardAppearance = appearance
98+
navigationController.navigationBar.scrollEdgeAppearance = appearance
99+
navigationController.navigationBar.compactAppearance = appearance
100+
101+
navigationController.navigationBar.setNeedsLayout()
102+
navigationController.navigationBar.layoutIfNeeded()
103+
}
104+
105+
for child in viewController.children {
106+
updateNavigationBars(in: child, with: appearance)
107+
}
108+
109+
if let presented = viewController.presentedViewController {
110+
updateNavigationBars(in: presented, with: appearance)
111+
}
112+
}
113+
#endif
114+
}

0 commit comments

Comments
 (0)