diff --git a/README.md b/README.md index 9c7859c..e013e14 100644 --- a/README.md +++ b/README.md @@ -104,6 +104,7 @@ Modifier | Description `.keyboardType(_ type: UIKeyboardType)` | Modifies the text field’s **keyboard type**. 📩 `.autocapitalization(_ style: UITextAutocapitalizationType)` | Modifies the text field’s **autocapitalization** style. 🔡 `.returnKeyType(_ type: UIReturnKeyType)` | Modifies the text field’s **return key** type. ✅ +`.characterLimit(_ limit: Int?)` | Sets the maximum amount of characters allowed in this text field. `.isSecure(_ isSecure: Bool)` | Modifies the text field’s **secure entry** settings. 🔒 `.clearsOnBeginEditing(_ shouldClear: Bool)` | Modifies the **clear-on-begin-editing** setting of a text field. ❌ `clearsOnInsertion(_ shouldClear: Bool)` | Modifies the **clear-on-insertion** setting of a text field. 👆 diff --git a/Sources/iTextField/iTextField+ViewModifiers.swift b/Sources/iTextField/iTextField+ViewModifiers.swift index a1804b0..09bb420 100644 --- a/Sources/iTextField/iTextField+ViewModifiers.swift +++ b/Sources/iTextField/iTextField+ViewModifiers.swift @@ -10,6 +10,16 @@ import UIKit @available(iOS 13.0, *) extension iTextField { + + /// Sets the maximum amount of characters allowed in this text field. + /// - Parameter limit: the maximum amount of characters allowed + /// - Returns: An updated text field limited to limit + public func characterLimit(_ limit: Int?) -> iTextField { + var view = self + view.characterLimit = limit + return view + } + /// Modifies the text field’s **font** from a `UIFont` object. 🔠🔡 /// - Parameter font: The desired font 🅰️🆗 /// - Returns: An updated text field using the desired font 💬 diff --git a/Sources/iTextField/iTextField.swift b/Sources/iTextField/iTextField.swift index c2e4e14..24f98ff 100644 --- a/Sources/iTextField/iTextField.swift +++ b/Sources/iTextField/iTextField.swift @@ -33,6 +33,7 @@ public struct iTextField: UIViewRepresentable { var autocapitalization: UITextAutocapitalizationType = .sentences var keyboardType: UIKeyboardType = .default var returnKeyType: UIReturnKeyType = .default + var characterLimit: Int? = nil var isSecure = false var isUserInteractionEnabled = true @@ -169,18 +170,22 @@ public struct iTextField: UIViewRepresentable { } public func makeCoordinator() -> Coordinator { - return Coordinator(text: $text, - isEditing: isEditing, - didBeginEditing: didBeginEditing, - didChange: didChange, - didEndEditing: didEndEditing, - shouldReturn: shouldReturn, - shouldClear: shouldClear) + return Coordinator( + text: $text, + isEditing: isEditing, + characterLimit: characterLimit, + didBeginEditing: didBeginEditing, + didChange: didChange, + didEndEditing: didEndEditing, + shouldReturn: shouldReturn, + shouldClear: shouldClear + ) } public final class Coordinator: NSObject, UITextFieldDelegate { @Binding var text: String @Binding var isEditing: Bool + var characterLimit: Int? = nil var didBeginEditing: () -> Void var didChange: () -> Void @@ -190,6 +195,7 @@ public struct iTextField: UIViewRepresentable { init(text: Binding, isEditing: Binding, + characterLimit: Int?, didBeginEditing: @escaping () -> Void, didChange: @escaping () -> Void, didEndEditing: @escaping () -> Void, @@ -198,6 +204,7 @@ public struct iTextField: UIViewRepresentable { { self._text = text self._isEditing = isEditing + self.characterLimit = characterLimit self.didBeginEditing = didBeginEditing self.didChange = didChange self.didEndEditing = didEndEditing @@ -242,5 +249,16 @@ public struct iTextField: UIViewRepresentable { text = "" return false } + + public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { + //if there is a character limit set and new text will be greater than limt, then don't allow the newly proposed edit + if let limit = characterLimit, let text = textField.text { + if text.count + string.count > limit { + return false + } + } + + return true + } } }