Last active
June 22, 2021 18:25
-
-
Save laurenchen0631/a396feaa79eb3c30c4c6689f97c6f471 to your computer and use it in GitHub Desktop.
Swiftui CustomTextField
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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