Skip to content

Commit

Permalink
Refactor notes Field as well
Browse files Browse the repository at this point in the history
  • Loading branch information
marv-out committed Jun 30, 2024
1 parent 99da447 commit 49bc151
Show file tree
Hide file tree
Showing 8 changed files with 181 additions and 15 deletions.
29 changes: 21 additions & 8 deletions FreeAPS/Sources/Modules/AddCarbs/View/AddCarbsRootView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,21 +42,34 @@ extension AddCarbs {
HStack {
Text("Carbs").fontWeight(.semibold)
Spacer()
TextFieldWithToolBar(text: $state.carbs, placeholder: "0", shouldBecomeFirstResponder: true, numberFormatter: formatter)
TextFieldWithToolBar(
text: $state.carbs,
placeholder: "0",
shouldBecomeFirstResponder: true,
numberFormatter: formatter
)
Text(state.carbs > state.maxCarbs ? "⚠️" : "g").foregroundColor(.secondary)
}.padding(.vertical)

if state.useFPUconversion {
proteinAndFat()
}
HStack {
Text("Note").foregroundColor(.secondary)
TextField("", text: $state.note).multilineTextAlignment(.trailing)
if isFocused {
Button { isFocused = false } label: { Image(systemName: "keyboard.chevron.compact.down") }
.controlSize(.mini)
VStack {
HStack {
Text("Note").foregroundColor(.secondary)
TextFieldWithToolBarString(text: $state.note, placeholder: "", maxLength: 25)
if isFocused {
Button { isFocused = false } label: { Image(systemName: "keyboard.chevron.compact.down") }
.controlSize(.mini)
}
}.focused($isFocused)

HStack {
Spacer()
Text("\(state.note.count) / 25")
.foregroundStyle(.secondary)
}
}.focused($isFocused)
}
HStack {
Button {
state.useFPUconversion.toggle()
Expand Down
7 changes: 6 additions & 1 deletion FreeAPS/Sources/Modules/Bolus/View/BolusRootView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,12 @@ extension Bolus {
HStack {
Text("Amount")
Spacer()
TextFieldWithToolBar(text: $state.amount, placeholder: "0", shouldBecomeFirstResponder: true, numberFormatter: formatter)
TextFieldWithToolBar(
text: $state.amount,
placeholder: "0",
shouldBecomeFirstResponder: true,
numberFormatter: formatter
)
Text(state.amount > state.maxBolus ? "⚠️" : "U").foregroundColor(.secondary)
}
}
Expand Down
14 changes: 12 additions & 2 deletions FreeAPS/Sources/Modules/DataTable/View/DataTableRootView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,12 @@ extension DataTable {
Section {
HStack {
Text("New Glucose")
TextFieldWithToolBar(text: $state.manualGlucose, placeholder: " ... ", shouldBecomeFirstResponder: true, numberFormatter: glucoseFormatter)
TextFieldWithToolBar(
text: $state.manualGlucose,
placeholder: " ... ",
shouldBecomeFirstResponder: true,
numberFormatter: glucoseFormatter
)
Text(state.units.rawValue).foregroundStyle(.secondary)
}
}
Expand Down Expand Up @@ -247,7 +252,12 @@ extension DataTable {
HStack {
Text("Amount")
Spacer()
TextFieldWithToolBar(text: $state.externalInsulinAmount, placeholder: "0", shouldBecomeFirstResponder: true, numberFormatter: insulinFormatter)
TextFieldWithToolBar(
text: $state.externalInsulinAmount,
placeholder: "0",
shouldBecomeFirstResponder: true,
numberFormatter: insulinFormatter
)
Text("U").foregroundColor(.secondary)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,11 @@ extension FPUConfig {
HStack {
Text("Override With A Factor Of ")
Spacer()
TextFieldWithToolBar(text: $state.individualAdjustmentFactor, placeholder: "0.5", numberFormatter: conversionFormatter)
TextFieldWithToolBar(
text: $state.individualAdjustmentFactor,
placeholder: "0.5",
numberFormatter: conversionFormatter
)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@ extension ManualTempBasal {
HStack {
Text("Amount")
Spacer()
TextFieldWithToolBar(text: $state.rate, placeholder: "0", shouldBecomeFirstResponder: true, numberFormatter: formatter)
TextFieldWithToolBar(
text: $state.rate,
placeholder: "0",
shouldBecomeFirstResponder: true,
numberFormatter: formatter
)
Text("U/hr").foregroundColor(.secondary)
}
Picker(selection: $state.durationIndex, label: Text("Duration")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,11 @@ extension NotificationsConfig {
HStack {
Text("Carbs Required Threshold")
Spacer()
TextFieldWithToolBar(text: $state.carbsRequiredThreshold, placeholder: "0", numberFormatter: carbsFormatter)
TextFieldWithToolBar(
text: $state.carbsRequiredThreshold,
placeholder: "0",
numberFormatter: carbsFormatter
)
Text("g").foregroundColor(.secondary)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,11 @@ extension PreferencesEditor {
})
Text(field.displayName)
}
TextFieldWithToolBar(text: self.$state.sections[sectionIndex].fields[fieldIndex].decimalValue, placeholder: "0", numberFormatter: formatter)
TextFieldWithToolBar(
text: self.$state.sections[sectionIndex].fields[fieldIndex].decimalValue,
placeholder: "0",
numberFormatter: formatter
)
case .insulinCurve:
Picker(
selection: $state.sections[sectionIndex].fields[fieldIndex].insulinCurveValue,
Expand Down
121 changes: 121 additions & 0 deletions FreeAPS/Sources/Views/TextFieldWithToolBar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -185,3 +185,124 @@ extension UIApplication {
sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}
}

public struct TextFieldWithToolBarString: UIViewRepresentable {
@Binding var text: String
var placeholder: String
var textAlignment: NSTextAlignment = .right
var keyboardType: UIKeyboardType = .default
var autocapitalizationType: UITextAutocapitalizationType = .none
var autocorrectionType: UITextAutocorrectionType = .no
var shouldBecomeFirstResponder: Bool = false
var maxLength: Int? = nil
var isDismissible: Bool = true

public func makeUIView(context: Context) -> UITextField {
let textField = UITextField()
context.coordinator.textField = textField
textField.inputAccessoryView = isDismissible ? makeDoneToolbar(for: textField, context: context) : nil
textField.addTarget(context.coordinator, action: #selector(Coordinator.editingDidBegin), for: .editingDidBegin)
textField.delegate = context.coordinator
textField.text = text
textField.placeholder = placeholder
textField.textAlignment = textAlignment
textField.keyboardType = keyboardType
textField.autocapitalizationType = autocapitalizationType
textField.autocorrectionType = autocorrectionType
textField.adjustsFontSizeToFitWidth = true
return textField
}

private func makeDoneToolbar(for textField: UITextField, context: Context) -> UIToolbar {
let toolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 50))
let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let doneButton = UIBarButtonItem(
image: UIImage(systemName: "keyboard.chevron.compact.down"),
style: .done,
target: textField,
action: #selector(UITextField.resignFirstResponder)
)
let clearButton = UIBarButtonItem(
image: UIImage(systemName: "trash"),
style: .plain,
target: context.coordinator,
action: #selector(Coordinator.clearText)
)

toolbar.items = [clearButton, flexibleSpace, doneButton]
toolbar.sizeToFit()
return toolbar
}

public func updateUIView(_ textField: UITextField, context: Context) {
if textField.text != text {
textField.text = text
}

textField.textAlignment = textAlignment
textField.keyboardType = keyboardType
textField.autocapitalizationType = autocapitalizationType
textField.autocorrectionType = autocorrectionType

if shouldBecomeFirstResponder, !context.coordinator.didBecomeFirstResponder {
if textField.window != nil, textField.becomeFirstResponder() {
context.coordinator.didBecomeFirstResponder = true
}
} else if !shouldBecomeFirstResponder, context.coordinator.didBecomeFirstResponder {
context.coordinator.didBecomeFirstResponder = false
}
}

public func makeCoordinator() -> Coordinator {
Coordinator(self, maxLength: maxLength)
}

public final class Coordinator: NSObject {
var parent: TextFieldWithToolBarString
var textField: UITextField?
let maxLength: Int?
var didBecomeFirstResponder = false

init(_ parent: TextFieldWithToolBarString, maxLength: Int?) {
self.parent = parent
self.maxLength = maxLength
}

@objc fileprivate func clearText() {
parent.text = ""
textField?.text = ""
}

@objc fileprivate func editingDidBegin(_ textField: UITextField) {
DispatchQueue.main.async {
textField.moveCursorToEnd()
}
}
}
}

extension TextFieldWithToolBarString.Coordinator: UITextFieldDelegate {
public func textField(
_ textField: UITextField,
shouldChangeCharactersIn range: NSRange,
replacementString string: String
) -> Bool {
if let maxLength = parent.maxLength {
// Get the current text, including the proposed change
let currentText = textField.text ?? ""
let newLength = currentText.count + string.count - range.length
if newLength > maxLength {
return false
}
}

DispatchQueue.main.async {
if let textFieldText = textField.text as NSString? {
let newText = textFieldText.replacingCharacters(in: range, with: string)
self.parent.text = newText
}
}

return true
}
}

0 comments on commit 49bc151

Please sign in to comment.