Skip to content

Instantly share code, notes, and snippets.

@laurenchen0631
Last active June 22, 2021 18:25
Show Gist options
  • Save laurenchen0631/a396feaa79eb3c30c4c6689f97c6f471 to your computer and use it in GitHub Desktop.
Save laurenchen0631/a396feaa79eb3c30c4c6689f97c6f471 to your computer and use it in GitHub Desktop.
Swiftui CustomTextField
// customized text field based on @Anshuman Singh https://stackoverflow.com/questions/58311022/autofocus-textfield-programmatically-in-swiftui
import SwiftUI
struct CustomTextField: UIViewRepresentable {
class Coordinator: NSObject, UITextFieldDelegate {
@Binding var textInput: String
@Binding var nextResponder: Bool?
@Binding var isResponder: Bool?
var maxLength: Int?
var onSubmit: (() -> Void)?
init(
text: Binding<String>,
nextResponder: Binding<Bool?>,
isResponder: Binding<Bool?>,
maxLength: Int?,
onSubmit: (() -> Void)?
) {
_textInput = text
_isResponder = isResponder
_nextResponder = nextResponder
self.maxLength = maxLength
self.onSubmit = onSubmit
}
func textField(
_ textField: UITextField,
shouldChangeCharactersIn range: NSRange,
replacementString string: String
) -> Bool {
guard let maxLength = maxLength else {
return true
}
guard let textFieldText = textField.text,
let rangeOfTextToReplace = Range(range, in: textFieldText) else {
return false
}
let substringToReplace = textFieldText[rangeOfTextToReplace]
let count = textFieldText.count - substringToReplace.count + string.count
return count <= maxLength
}
func textFieldDidChangeSelection(_ textField: UITextField) {
if textField.markedTextRange == nil {
textInput = textField.text ?? ""
}
}
func textFieldDidBeginEditing(_: UITextField) {
DispatchQueue.main.async {
self.isResponder = true
}
}
func textFieldShouldReturn(_: UITextField) -> Bool {
if let onSubmit = onSubmit {
onSubmit()
}
DispatchQueue.main.async {
self.isResponder = false
if self.nextResponder != nil {
self.nextResponder = true
}
}
return true
}
}
@Binding var text: String
@Binding var nextResponder: Bool?
@Binding var isResponder: Bool?
var isSecured: Bool = false
var keyboard: UIKeyboardType
var returnKeyType: UIReturnKeyType?
var maxLength: Int?
var textColor: UIColor = .white
var placeholder: String?
var placeholderColor: UIColor = .white
var onSubmit: (() -> Void)?
func makeUIView(context: UIViewRepresentableContext<CustomTextField>) -> UITextField {
let textField = UITextField(frame: .zero)
textField.isSecureTextEntry = isSecured
textField.autocapitalizationType = .none
textField.autocorrectionType = .no
textField.keyboardType = keyboard
textField.returnKeyType = returnKeyType ?? UIReturnKeyType.default
textField.textColor = textColor
textField.delegate = context.coordinator
if placeholder != nil {
textField.attributedPlaceholder = NSAttributedString(
string: placeholder!,
attributes: [NSAttributedString.Key.foregroundColor: placeholderColor]
)
}
return textField
}
func makeCoordinator() -> CustomTextField.Coordinator {
Coordinator(
text: $text,
nextResponder: $nextResponder,
isResponder: $isResponder,
maxLength: maxLength,
onSubmit: onSubmit
)
}
func updateUIView(_ uiView: UITextField, context _: UIViewRepresentableContext<CustomTextField>) {
uiView.text = text
if isResponder ?? false {
uiView.becomeFirstResponder()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment