added keyboard handling
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
parent
abe93d2298
commit
69482c2c7a
@ -22,7 +22,7 @@ public class FormSection: UIStackView {
|
||||
}
|
||||
}
|
||||
|
||||
private var titleLabel = Label().with { $0.isHidden = true; $0.textStyle = .boldBodyLarge }
|
||||
private var titleLabel = Label().with { $0.isHidden = true; $0.textStyle = .boldBodyLarge; }
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
@ -164,10 +164,8 @@ public class BaseViewController<Component: UIView>: UIViewController, Initable {
|
||||
super.viewDidLoad()
|
||||
view.backgroundColor = .white
|
||||
|
||||
let top = UIView.makeWrapper(for: contentTopView, edgeSpacing: 16, isTrailing: false)
|
||||
|
||||
// Add the top and bottom views to the stack view
|
||||
stackView.addArrangedSubview(top)
|
||||
stackView.addArrangedSubview(contentTopView.makeWrapper(edgeSpacing: 16))
|
||||
stackView.addArrangedSubview(bottomScrollView)
|
||||
|
||||
// Add the stack view to the view controller's view
|
||||
@ -178,7 +176,7 @@ public class BaseViewController<Component: UIView>: UIViewController, Initable {
|
||||
stackView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
|
||||
stackView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
|
||||
stackView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
|
||||
stackView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)
|
||||
stackView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -25)
|
||||
])
|
||||
|
||||
bottomScrollView.addSubview(contentBottomView)
|
||||
@ -191,7 +189,7 @@ public class BaseViewController<Component: UIView>: UIViewController, Initable {
|
||||
contentBottomView.bottomAnchor.constraint(equalTo: bottomScrollView.bottomAnchor),
|
||||
contentBottomView.widthAnchor.constraint(equalTo: bottomScrollView.widthAnchor)
|
||||
])
|
||||
|
||||
|
||||
contentBottomView.addSubview(formStackView)
|
||||
formStackView.pinToSuperView(.init(top: 0, left: 16, bottom: 0, right: edgeSpacing))
|
||||
|
||||
@ -202,6 +200,52 @@ public class BaseViewController<Component: UIView>: UIViewController, Initable {
|
||||
picker.isHidden = true
|
||||
|
||||
setupForm()
|
||||
|
||||
NotificationCenter.default
|
||||
.publisher(for: UIResponder.keyboardWillShowNotification)
|
||||
.sink { [weak self] notification in
|
||||
self?.keyboardWillShow(notification: notification)
|
||||
}.store(in: &subscribers)
|
||||
|
||||
NotificationCenter.default
|
||||
.publisher(for: UIResponder.keyboardWillHideNotification)
|
||||
.sink { [weak self] notification in
|
||||
self?.keyboardWillHide(notification: notification)
|
||||
}.store(in: &subscribers)
|
||||
|
||||
NotificationCenter.default
|
||||
.publisher(for: UITextField.textDidBeginEditingNotification)
|
||||
.sink { [weak self] notification in
|
||||
guard let self, let textField = notification.object as? UITextField else { return }
|
||||
self.activeTextField = textField
|
||||
}.store(in: &subscribers)
|
||||
|
||||
NotificationCenter.default
|
||||
.publisher(for: UITextField.textDidEndEditingNotification)
|
||||
.sink { [weak self] notification in
|
||||
self?.activeTextField?.resignFirstResponder()
|
||||
self?.activeTextField = nil
|
||||
}.store(in: &subscribers)
|
||||
}
|
||||
|
||||
func isViewHiddenByKeyboard(view: UIView, keyboardFrame: CGRect) -> Bool {
|
||||
let viewFrameInWindow = view.convert(view.bounds, to: nil)
|
||||
let inetersectionFrame = viewFrameInWindow.intersection(keyboardFrame)
|
||||
return inetersectionFrame.height > 0
|
||||
}
|
||||
|
||||
func keyboardWillShow(notification: UIKit.Notification) {
|
||||
if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
|
||||
if let activeTextField, self.view.frame.origin.y == 0, isViewHiddenByKeyboard(view: activeTextField, keyboardFrame: keyboardSize) {
|
||||
self.view.frame.origin.y -= keyboardSize.height
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func keyboardWillHide(notification: UIKit.Notification) {
|
||||
if self.view.frame.origin.y != 0 {
|
||||
self.view.frame.origin.y = 0
|
||||
}
|
||||
}
|
||||
|
||||
public func setupForm() {
|
||||
@ -236,31 +280,25 @@ public class BaseViewController<Component: UIView>: UIViewController, Initable {
|
||||
return formStackView.addFormRow(label: label, view: view)
|
||||
}
|
||||
|
||||
var activeTextField: UITextField?
|
||||
|
||||
open func setup() {
|
||||
|
||||
if let textFields = allTextFields() {
|
||||
for textField in textFields {
|
||||
if textField.isNumeric {
|
||||
let keypadToolbar: UIToolbar = UIToolbar()
|
||||
|
||||
// add a done button to the numberpad
|
||||
keypadToolbar.items=[
|
||||
UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace, target: self, action: nil),
|
||||
UIBarButtonItem(title: "Done", style: UIBarButtonItem.Style.done, target: textField, action: #selector(UITextField.resignFirstResponder))
|
||||
]
|
||||
keypadToolbar.sizeToFit()
|
||||
|
||||
// add a toolbar with a done button above the number pad
|
||||
textField.inputAccessoryView = keypadToolbar
|
||||
textField.keyboardType = .numberPad
|
||||
}
|
||||
let keypadToolbar: UIToolbar = UIToolbar()
|
||||
|
||||
// add a done button to the numberpad
|
||||
keypadToolbar.items=[
|
||||
UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace, target: self, action: nil),
|
||||
UIBarButtonItem(title: "Done", style: UIBarButtonItem.Style.done, target: textField, action: #selector(UITextField.resignFirstResponder))
|
||||
]
|
||||
keypadToolbar.sizeToFit()
|
||||
|
||||
// add a toolbar with a done button above the number pad
|
||||
textField.inputAccessoryView = keypadToolbar
|
||||
textField.keyboardType = textField.isNumeric ? .numberPad : .alphabet
|
||||
textField.returnKeyType = .done
|
||||
textField
|
||||
.publisher(for: .editingDidEndOnExit)
|
||||
.sink { textField in
|
||||
textField.resignFirstResponder()
|
||||
}
|
||||
.store(in: &subscribers)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -270,4 +308,5 @@ public class BaseViewController<Component: UIView>: UIViewController, Initable {
|
||||
}
|
||||
|
||||
open func allTextFields() -> [TextField]? { nil }
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user