Skip to content

Commit 9c73a6e

Browse files
authored
fix(widgets): fix calculator widget keyboard dismiss (#513)
* fix(widgets): fix calculator widget dismiss * chore: update changelog * fix(widgets): fix calculator widget fiat symbols
1 parent 71b6394 commit 9c73a6e

6 files changed

Lines changed: 66 additions & 3 deletions

File tree

Bitkit/AppScene.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ struct AppScene: View {
2727
@StateObject private var transferTracking: TransferTrackingManager
2828
@StateObject private var channelDetails = ChannelDetailsViewModel.shared
2929
@StateObject private var migrations = MigrationsService.shared
30+
@State private var keyboardManager = KeyboardManager()
3031

3132
@State private var hideSplash = false
3233
@State private var removeSplash = false
@@ -134,6 +135,7 @@ struct AppScene: View {
134135
.environmentObject(tagManager)
135136
.environmentObject(transferTracking)
136137
.environmentObject(channelDetails)
138+
.environment(keyboardManager)
137139
.onAppear {
138140
if !settings.pinEnabled {
139141
isPinVerified = true

Bitkit/Components/TabBar/TabBar.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ struct TabBar: View {
3535
}
3636
}
3737
.animation(.easeInOut, value: shouldShow)
38-
.ignoresSafeArea(.keyboard)
3938
.bottomSafeAreaPadding()
4039
}
4140

Bitkit/Components/Widgets/CalculatorWidget.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ struct CalculatorWidget: View {
102102

103103
CurrencyInputRow(
104104
icon: CircularIcon(
105-
icon: BodyMSBText(currency.symbol, textColor: .brandAccent),
105+
icon: BodyMSBText(currency.symbol.count > 2 ? String(currency.symbol.prefix(1)) : currency.symbol, textColor: .brandAccent),
106106
backgroundColor: .gray6,
107107
size: 32
108108
),
@@ -134,6 +134,14 @@ struct CalculatorWidget: View {
134134
}
135135
}
136136
}
137+
.toolbar {
138+
ToolbarItemGroup(placement: .keyboard) {
139+
Spacer()
140+
Button(t("common__done")) {
141+
focusedField = nil
142+
}
143+
}
144+
}
137145
}
138146
.onAppear {
139147
// Initialize fiat amount on first load
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import SwiftUI
2+
import UIKit
3+
4+
@Observable
5+
final class KeyboardManager {
6+
var isPresented = false
7+
var height: CGFloat = 0
8+
9+
private var notificationTokens: [NSObjectProtocol] = []
10+
11+
init() {
12+
let willShowToken = NotificationCenter.default.addObserver(
13+
forName: UIResponder.keyboardWillShowNotification,
14+
object: nil,
15+
queue: .main
16+
) { [weak self] notification in
17+
guard let self else { return }
18+
let frame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect
19+
height = frame?.height ?? 0
20+
isPresented = true
21+
}
22+
23+
let willHideToken = NotificationCenter.default.addObserver(
24+
forName: UIResponder.keyboardWillHideNotification,
25+
object: nil,
26+
queue: .main
27+
) { [weak self] _ in
28+
guard let self else { return }
29+
height = 0
30+
isPresented = false
31+
}
32+
33+
notificationTokens = [willShowToken, willHideToken]
34+
}
35+
36+
deinit {
37+
// Remove observers to prevent memory leaks
38+
notificationTokens.forEach { NotificationCenter.default.removeObserver($0) }
39+
}
40+
}

Bitkit/Views/Home/HomeWidgetsView.swift

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,21 @@ import SwiftUI
22

33
struct HomeWidgetsView: View {
44
@EnvironmentObject var app: AppViewModel
5+
@Environment(KeyboardManager.self) private var keyboard
56
@EnvironmentObject var navigation: NavigationViewModel
67
@EnvironmentObject var settings: SettingsViewModel
78
@EnvironmentObject var suggestionsManager: SuggestionsManager
89
@EnvironmentObject var wallet: WalletViewModel
910
@EnvironmentObject var widgets: WidgetsViewModel
11+
1012
@Binding var isEditingWidgets: Bool
1113

14+
private var bottomPadding: CGFloat {
15+
// Keep the calculator widget fully scrollable above the keyboard.
16+
let inset = keyboard.height + ScreenLayout.bottomSpacing
17+
return keyboard.isPresented ? inset : ScreenLayout.bottomPaddingWithSafeArea
18+
}
19+
1220
/// Widgets to display; suggestions widget is hidden when it would show no cards (unless editing).
1321
private var widgetsToShow: [Widget] {
1422
widgets.savedWidgets.filter { widget in
@@ -46,9 +54,11 @@ struct HomeWidgetsView: View {
4654
}
4755
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
4856
.padding(.top, ScreenLayout.topPaddingWithSafeArea)
49-
.padding(.bottom, ScreenLayout.bottomPaddingWithSafeArea)
57+
.padding(.bottom, bottomPadding)
5058
.padding(.horizontal)
5159
}
60+
// Dismiss (calculator widget) keyboard when scrolling
61+
.scrollDismissesKeyboard(.interactively)
5262
}
5363

5464
private func rowContent(_ widget: Widget) -> some View {

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Fixed
11+
- Stabilize Home widgets calculator keyboard behavior by improving keyboard avoidance and adding a keyboard "Done" button. #513
12+
- In the calculator widget, show only the first character of multi-character currency symbols. #513
13+
1014
[Unreleased]: https://github.com/synonymdev/bitkit-ios/compare/v2.1.2...HEAD

0 commit comments

Comments
 (0)