Skip to content

Commit b8ccd31

Browse files
authored
Merge pull request #5465 from woocommerce/issue/simple-payments-ios-15
2 parents 1206104 + bfff991 commit b8ccd31

File tree

4 files changed

+136
-5
lines changed

4 files changed

+136
-5
lines changed

WooCommerce/Classes/ViewRelated/Orders/Simple Payments/Amount/SimplePaymentsAmount.swift

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,12 @@ struct SimplePaymentsAmount: View {
9999
.secondaryBodyStyle()
100100

101101
// Amount Textfield
102-
TextField(viewModel.amountPlaceholder, text: $viewModel.amount)
103-
.font(.system(size: Layout.amountFontSize(scale: scale), weight: .bold, design: .default))
104-
.foregroundColor(Color(.text))
105-
.multilineTextAlignment(.center)
102+
BindableTextfield(viewModel.amountPlaceholder, text: $viewModel.amount)
103+
.font(.systemFont(ofSize: Layout.amountFontSize(scale: scale), weight: .bold))
104+
.foregroundColor(.text)
105+
.textAlignment(.center)
106106
.keyboardType(.decimalPad)
107+
.fixedSize()
107108

108109
Spacer()
109110

@@ -132,6 +133,7 @@ struct SimplePaymentsAmount: View {
132133
})
133134
}
134135
}
136+
.wooNavigationBarStyle()
135137
}
136138
}
137139

WooCommerce/Classes/ViewRelated/Orders/Simple Payments/Amount/SimplePaymentsAmountViewModel.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import Yosemite
55
///
66
final class SimplePaymentsAmountViewModel: ObservableObject {
77

8-
/// Stores amount entered by the merchant.
8+
/// Stores the amount(formatted) entered by the merchant.
99
///
1010
@Published var amount: String = "" {
1111
didSet {
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
import Foundation
2+
import SwiftUI
3+
4+
/// `UITextfield` wrapper reads and writes to provided binding value.
5+
/// Needed because iOS 15 won't allow us to intercept correctly the binding value in the original `SwiftUI` component.
6+
/// Feel free to add modifiers as it is needed.
7+
///
8+
struct BindableTextfield: UIViewRepresentable {
9+
10+
/// Placeholder of the textfield.
11+
///
12+
let placeHolder: String?
13+
14+
/// Binding to read content from and write content to.
15+
///
16+
@Binding var text: String
17+
18+
/// Textfield font.
19+
///
20+
var font = UIFont.body
21+
22+
/// Textfield keyboard.
23+
///
24+
var keyboardType = UIKeyboardType.default
25+
26+
/// Textfield text color.
27+
///
28+
var foregroundColor = UIColor.text
29+
30+
/// Textfield text alignment.
31+
///
32+
var textAlignment = NSTextAlignment.left
33+
34+
init(_ placeholder: String?, text: Binding<String>) {
35+
self.placeHolder = placeholder
36+
self._text = text
37+
}
38+
39+
/// Creates view with the initial configuration.
40+
///
41+
func makeUIView(context: Context) -> UITextField {
42+
let textfield = UITextField()
43+
textfield.delegate = context.coordinator
44+
return textfield
45+
}
46+
47+
/// Creates coordinator.
48+
///
49+
func makeCoordinator() -> Coordinator {
50+
Coordinator(_text)
51+
}
52+
53+
/// Updates underlying view.
54+
///
55+
func updateUIView(_ uiView: UITextField, context: Context) {
56+
uiView.placeholder = placeHolder
57+
uiView.text = text
58+
uiView.font = font
59+
uiView.textColor = foregroundColor
60+
uiView.textAlignment = textAlignment
61+
uiView.keyboardType = keyboardType
62+
}
63+
}
64+
65+
// MARK: Coordinator
66+
67+
extension BindableTextfield {
68+
/// Coordinator needed to listen to the `TextField` delegate and relay the input content to the binding value.
69+
///
70+
final class Coordinator: NSObject, UITextFieldDelegate {
71+
72+
/// Binding to set content from the `TextField` delegate.
73+
///
74+
@Binding var text: String
75+
76+
init(_ text: Binding<String>) {
77+
self._text = text
78+
}
79+
80+
/// Relays the input value to the binding variable.
81+
///
82+
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
83+
if let currentInput = textField.text, let inputRange = Range(range, in: currentInput) {
84+
text = currentInput.replacingCharacters(in: inputRange, with: string)
85+
} else {
86+
text = string
87+
}
88+
return false
89+
}
90+
}
91+
}
92+
93+
94+
// MARK: Modifiers
95+
96+
extension BindableTextfield {
97+
/// Updates the textfield font.
98+
///
99+
func font(_ font: UIFont) -> Self {
100+
var copy = self
101+
copy.font = font
102+
return copy
103+
}
104+
105+
/// Updates the textfield foreground color.
106+
func foregroundColor(_ color: UIColor) -> Self {
107+
var copy = self
108+
copy.foregroundColor = color
109+
return copy
110+
}
111+
112+
/// Updates the textfield text alignment.
113+
func textAlignment(_ alignment: NSTextAlignment) -> Self {
114+
var copy = self
115+
copy.textAlignment = alignment
116+
return copy
117+
}
118+
119+
/// Updates the textfield keyboard type.
120+
func keyboardType(_ type: UIKeyboardType) -> Self {
121+
var copy = self
122+
copy.keyboardType = type
123+
return copy
124+
}
125+
}

WooCommerce/WooCommerce.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,7 @@
452452
26B119C224D1CD3500FED5C7 /* WooConstantsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26B119C124D1CD3500FED5C7 /* WooConstantsTests.swift */; };
453453
26B3D8A0252235C50054C319 /* RefundShippingDetailsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26B3D89F252235C50054C319 /* RefundShippingDetailsViewModel.swift */; };
454454
26B3EC622744772A0075EAE6 /* SimplePaymentsSummaryViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26B3EC612744772A0075EAE6 /* SimplePaymentsSummaryViewModelTests.swift */; };
455+
26B3EC642745916F0075EAE6 /* BindableTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26B3EC632745916F0075EAE6 /* BindableTextField.swift */; };
455456
26B98758273C5BE30090E8CA /* EditCustomerNoteViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26B98757273C5BE30090E8CA /* EditCustomerNoteViewModelProtocol.swift */; };
456457
26B9875D273C6A830090E8CA /* SimplePaymentsNoteViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26B9875C273C6A830090E8CA /* SimplePaymentsNoteViewModel.swift */; };
457458
26B9875F273CB6AA0090E8CA /* SimplePaymentsNoteViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26B9875E273CB6AA0090E8CA /* SimplePaymentsNoteViewModelTests.swift */; };
@@ -1929,6 +1930,7 @@
19291930
26B119C124D1CD3500FED5C7 /* WooConstantsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WooConstantsTests.swift; sourceTree = "<group>"; };
19301931
26B3D89F252235C50054C319 /* RefundShippingDetailsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RefundShippingDetailsViewModel.swift; sourceTree = "<group>"; };
19311932
26B3EC612744772A0075EAE6 /* SimplePaymentsSummaryViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimplePaymentsSummaryViewModelTests.swift; sourceTree = "<group>"; };
1933+
26B3EC632745916F0075EAE6 /* BindableTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BindableTextField.swift; sourceTree = "<group>"; };
19321934
26B98757273C5BE30090E8CA /* EditCustomerNoteViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditCustomerNoteViewModelProtocol.swift; sourceTree = "<group>"; };
19331935
26B9875C273C6A830090E8CA /* SimplePaymentsNoteViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimplePaymentsNoteViewModel.swift; sourceTree = "<group>"; };
19341936
26B9875E273CB6AA0090E8CA /* SimplePaymentsNoteViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimplePaymentsNoteViewModelTests.swift; sourceTree = "<group>"; };
@@ -4620,6 +4622,7 @@
46204622
26C6E8E926E8FD3900C7BB0F /* LazyView.swift */,
46214623
26C6E8EB26E8FF4800C7BB0F /* LazyNavigationLink.swift */,
46224624
AE6DBE3A2732CAAD00957E7A /* AdaptiveStack.swift */,
4625+
26B3EC632745916F0075EAE6 /* BindableTextField.swift */,
46234626
);
46244627
path = "SwiftUI Components";
46254628
sourceTree = "<group>";
@@ -8257,6 +8260,7 @@
82578260
02F843DA273646A30017FE12 /* JetpackBenefitsBanner.swift in Sources */,
82588261
027D4A8D2526FD1800108626 /* SettingsViewController.swift in Sources */,
82598262
02E262C9238D0AD300B79588 /* ProductStockStatusListSelectorCommand.swift in Sources */,
8263+
26B3EC642745916F0075EAE6 /* BindableTextField.swift in Sources */,
82608264
CE2A9FC823C3D2D4002BEC1C /* RefundedProductsDataSource.swift in Sources */,
82618265
5783FB3F25D7369F00B9984B /* WooAnalyticsEventPropertyType.swift in Sources */,
82628266
CECC759523D6057E00486676 /* OrderItem+Woo.swift in Sources */,

0 commit comments

Comments
 (0)