Tusker/Tusker/Views/FocusableTextField.swift

74 lines
2.2 KiB
Swift

//
// FocusableTextField.swift
// Tusker
//
// Created by Shadowfacts on 11/2/20.
// Copyright © 2020 Shadowfacts. All rights reserved.
//
import SwiftUI
struct FocusableTextField: UIViewRepresentable {
typealias UIViewType = UITextField
let placeholder: String
let text: Binding<String>
let becomeFirstResponder: Binding<Bool>?
let onCommit: (() -> Void)?
init(placeholder: String, text: Binding<String>, becomeFirstResponder: Binding<Bool>? = nil, onCommit: (() -> Void)? = nil) {
self.placeholder = placeholder
self.text = text
self.becomeFirstResponder = becomeFirstResponder
self.onCommit = onCommit
}
func makeUIView(context: Context) -> UITextField {
let field = UITextField()
field.delegate = context.coordinator
field.addTarget(context.coordinator, action: #selector(Coordinator.didChange(_:)), for: .editingChanged)
field.addTarget(context.coordinator, action: #selector(Coordinator.didEnd(_:)), for: .primaryActionTriggered)
return field
}
func updateUIView(_ uiView: UITextField, context: Context) {
uiView.placeholder = placeholder
uiView.text = text.wrappedValue
context.coordinator.text = text
context.coordinator.onCommit = onCommit
if becomeFirstResponder?.wrappedValue == true {
DispatchQueue.main.async {
uiView.becomeFirstResponder()
becomeFirstResponder?.wrappedValue = false
}
}
}
func makeCoordinator() -> Coordinator {
return Coordinator(text: text)
}
class Coordinator: NSObject, UITextFieldDelegate {
var text: Binding<String>
var onCommit: (() -> Void)?
init(text: Binding<String>) {
self.text = text
}
@objc func didChange(_ textField: UITextField) {
text.wrappedValue = textField.text ?? ""
}
@objc func didEnd(_ textField: UITextField) {
onCommit?()
}
func textFieldDidEndEditing(_ textField: UITextField) {
onCommit?()
}
}
}