これには他のトピックがあることは知っていますが、それを実装する方法を見つけることができないようです。
UITextFieldを5文字のみに制限しようとしています
英数字と-および。および_
私はこのコードを見ました
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange,
replacementString string: String) -> Bool
{
let maxLength = 4
let currentString: NSString = textField.text
let newString: NSString =
currentString.stringByReplacingCharactersInRange(range, withString: string)
return newString.length <= maxLength
}
そして
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
let length = count(textField.text.utf16) + count(string.utf16) - range.length
return length <= 10
}
私は実際にそれを実装する方法や、UITextFieldという名前のカスタムのためにどの「テキストフィールド」を交換すべきかわからないだけです
View Controllerは、次のようにUITextFieldDelegate
に準拠する必要があります。
class MyViewController: UIViewController, UITextFieldDelegate {
}
テキストフィールドのデリゲートを設定します:myTextField.delegate = self
textField(_:shouldChangeCharactersInRange:replacementString:)
すべて一緒に:
class MyViewController: UIViewController,UITextFieldDelegate //set delegate to class
@IBOutlet var mytextField: UITextField // textfield variable
override func viewDidLoad() {
super.viewDidLoad()
mytextField.delegate = self //set delegate
}
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange,
replacementString string: String) -> Bool
{
let maxLength = 4
let currentString: NSString = textField.text
let newString: NSString =
currentString.stringByReplacingCharactersInRange(range, withString: string)
return newString.length <= maxLength
}
Swift 4の場合
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let maxLength = 1
let currentString: NSString = textField.text! as NSString
let newString: NSString =
currentString.replacingCharacters(in: range, with: string) as NSString
return newString.length <= maxLength
}
指定された文字セットのみを特定のテキストフィールドに入力できるようにします
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
var result = true
if mytextField == numberField {
if count(string) > 0 {
let disallowedCharacterSet = NSCharacterSet(charactersInString: "0123456789.-").invertedSet
let replacementStringIsLegal = string.rangeOfCharacterFromSet(disallowedCharacterSet) == nil
result = replacementStringIsLegal
}
}
return result
}
この問題に関してオンラインで表示されるサンプルコードの多くは非常に古いことに注意してください。
以下をプロジェクトのSwiftファイルに貼り付けます。ファイルには任意の名前を付けることができます。たとえば、「Handy.Swift」
テキストフィールドに.maxLength
が追加されました。
開発中にストーリーボードでその値を設定しても、アプリの実行中にコードで値を設定してもまったく問題ありません。
// simply have this in any Swift file, say, Handy.Swift
import UIKit
private var __maxLengths = [UITextField: Int]()
extension UITextField {
@IBInspectable var maxLength: Int {
get {
guard let l = __maxLengths[self] else {
return 150 // (global default-limit. or just, Int.max)
}
return l
}
set {
__maxLengths[self] = newValue
addTarget(self, action: #selector(fix), for: .editingChanged)
}
}
func fix(textField: UITextField) {
let t = textField.text
textField.text = t?.prefix(maxLength)
}
}
とても簡単です。
脚注-最近では、SwiftでString
を安全に切り捨てるために、単に.prefix(n)
上記の修正により、プロジェクトのallテキストフィールドが修正されます。
単に1つの特定のテキストフィールドを「4」と言うだけに制限したい場合、それは...
class PinCodeEntry: UITextField {
override func didMoveToSuperview() {
super.didMoveToSuperview()
addTarget(self, action: #selector(fixMe), for: .editingChanged)
}
@objc private func fixMe() { text = text?.prefix(4) }
}
ふう! これですべてです
(ところで、これはUITextViewに関連する同様の非常に便利なヒントです、 https://stackoverflow.com/a/42333832/294884 )
Swift 4、単に使用:
public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
return range.location < 10
}
Steven Schmatzが行った方法と同じですが、Swift 3.0を使用しました:
//max Length
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange,
replacementString string: String) -> Bool
{
let maxLength = 4
let currentString: NSString = textField.text! as NSString
let newString: NSString = currentString.replacingCharacters(in: range, with: string) as NSString
return newString.length <= maxLength
}
これには拡張がより便利だと思います。完全な回答を見る こちら
private var maxLengths = [UITextField: Int]()
// 2
extension UITextField {
// 3
@IBInspectable var maxLength: Int {
get {
// 4
guard let length = maxLengths[self] else {
return Int.max
}
return length
}
set {
maxLengths[self] = newValue
// 5
addTarget(
self,
action: #selector(limitLength),
forControlEvents: UIControlEvents.EditingChanged
)
}
}
func limitLength(textField: UITextField) {
// 6
guard let prospectiveText = textField.text
where prospectiveText.characters.count > maxLength else {
return
}
let selection = selectedTextRange
// 7
text = prospectiveText.substringWithRange(
Range<String.Index>(prospectiveText.startIndex ..< prospectiveText.startIndex.advancedBy(maxLength))
)
selectedTextRange = selection
}
}
上記のその他のソリューションでは、テキストフィールドマップにより保持サイクルが生成されます。また、maxLength
プロパティは、人工的なInt.max
構造の代わりに設定されていない場合、null可能にする必要があります。 maxLengthが変更されると、ターゲットは複数回設定されます。
ここではメモリリークやその他の修正を防ぐための弱いマップを使用したSwift4の更新されたソリューション
private var maxLengths = NSMapTable<UITextField, NSNumber>(keyOptions: NSPointerFunctions.Options.weakMemory, valueOptions: NSPointerFunctions.Options.strongMemory)
extension UITextField {
var maxLength: Int? {
get {
return maxLengths.object(forKey: self)?.intValue
}
set {
removeTarget(self, action: #selector(limitLength), for: .editingChanged)
if let newValue = newValue {
maxLengths.setObject(NSNumber(value: newValue), forKey: self)
addTarget(self, action: #selector(limitLength), for: .editingChanged)
} else {
maxLengths.removeObject(forKey: self)
}
}
}
@IBInspectable var maxLengthInspectable: Int {
get {
return maxLength ?? Int.max
}
set {
maxLength = newValue
}
}
@objc private func limitLength(_ textField: UITextField) {
guard let maxLength = maxLength, let prospectiveText = textField.text, prospectiveText.count > maxLength else {
return
}
let selection = selectedTextRange
text = String(prospectiveText[..<prospectiveText.index(from: maxLength)])
selectedTextRange = selection
}
}
私のSwift 4バージョンのshouldChangeCharactersIn
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange,
replacementString string: String) -> Bool {
guard let preText = textField.text as NSString?,
preText.replacingCharacters(in: range, with: string).count <= MAX_TEXT_LENGTH else {
return false
}
return true
}
この答えはSwift 4に対するもので、バックスペースを通過させる機能を備えているため、非常に簡単です。
func textField(_ textField: UITextField,
shouldChangeCharactersIn range: NSRange,
replacementString string: String) -> Bool {
return textField.text!.count < 10 || string == ""
}
アラジンの答えに何か付け加えることがあります:
View ControllerはUITextFieldDelegate
に準拠する必要があります
class MyViewController: UIViewController, UITextViewDelegate {
}
テキストフィールドのデリゲートを設定する:デリゲートを設定するには、テキストフィールドからストーリーボードのView Controllerへのドラッグを制御できます。これはコードで設定するよりも望ましいと思います
View Controllerにメソッドを実装します:textField(_:shouldChangeCharactersInRange:replacementString:)
デリゲートを使用しないシンプルなソリューション:
TEXT_FIELD.addTarget(self, action: #selector(editingChanged(sender:)), for: .editingChanged)
@objc private func editingChanged(sender: UITextField) {
if let text = sender.text, text.count >= MAX_LENGHT {
sender.text = String(text.dropLast(text.count - MAX_LENGHT))
return
}
}
@Frouoに基づいて補足的な回答をします。彼の答えは最も美しい方法だと思います。再利用できる一般的なコントロールであるためです。そして、ここにリークの問題はありません。
private var kAssociationKeyMaxLength: Int = 0
extension UITextField {
@IBInspectable var maxLength: Int {
get {
if let length = objc_getAssociatedObject(self, &kAssociationKeyMaxLength) as? Int {
return length
} else {
return Int.max
}
}
set {
objc_setAssociatedObject(self, &kAssociationKeyMaxLength, newValue, .OBJC_ASSOCIATION_RETAIN)
self.addTarget(self, action: #selector(checkMaxLength), for: .editingChanged)
}
}
//The method is used to cancel the check when use Chinese Pinyin input method.
//Becuase the alphabet also appears in the textfield when inputting, we should cancel the check.
func isInputMethod() -> Bool {
if let positionRange = self.markedTextRange {
if let _ = self.position(from: positionRange.start, offset: 0) {
return true
}
}
return false
}
func checkMaxLength(textField: UITextField) {
guard !self.isInputMethod(), let prospectiveText = self.text,
prospectiveText.count > maxLength
else {
return
}
let selection = selectedTextRange
let maxCharIndex = prospectiveText.index(prospectiveText.startIndex, offsetBy: maxLength)
text = prospectiveText.substring(to: maxCharIndex)
selectedTextRange = selection
}
}
この更新 Fattie answer
ありがとう
extension UITextField {
/// Runtime key
private struct AssociatedKeys {
/// max lenght key
static var maxlength: UInt8 = 0
/// temp string key
static var tempString: UInt8 = 0
}
/// Limit the maximum input length of the textfiled
@IBInspectable var maxLength: Int {
get {
return objc_getAssociatedObject(self, &AssociatedKeys.maxlength) as? Int ?? 0
}
set {
objc_setAssociatedObject(self, &AssociatedKeys.maxlength, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
addTarget(self, action: #selector(handleEditingChanged(textField:)), for: .editingChanged)
}
}
/// temp string
private var tempString: String? {
get {
return objc_getAssociatedObject(self, &AssociatedKeys.tempString) as? String
}
set {
objc_setAssociatedObject(self, &AssociatedKeys.tempString, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
/// When the text changes, process the amount of text in the input box so that its length is within the controllable range.
@objc private func handleEditingChanged(textField: UITextField) {
/// Special Processing for Chinese Input Method
guard markedTextRange == nil else { return }
if textField.text?.count == maxLength {
/// SET lastQualifiedString where text length == max lenght
tempString = textField.text
} else if textField.text?.count ?? 0 < maxLength {
/// clear lastQualifiedString when text lengeht > maxlength
tempString = nil
}
/// keep current text range in arcgives
let archivesEditRange: UITextRange?
if textField.text?.count ?? 0 > maxLength {
/// if text length > maxlength,remove last range,to move to -1 postion.
let position = textField.position(from: safeTextPosition(selectedTextRange?.start), offset: -1) ?? textField.endOfDocument
archivesEditRange = textField.textRange(from: safeTextPosition(position), to: safeTextPosition(position))
} else {
/// just set current select text range
archivesEditRange = selectedTextRange
}
/// main handle string max length
textField.text = tempString ?? String((textField.text ?? "").prefix(maxLength))
/// last config edit text range
textField.selectedTextRange = archivesEditRange
}
/// get safe textPosition
private func safeTextPosition(_ optionlTextPosition: UITextPosition?) -> UITextPosition {
/* beginningOfDocument -> The end of the the text document. */
return optionlTextPosition ?? endOfDocument
}
}
Swift4での作業
//ステップ1 UITextFieldDelegateを設定
class SignUPViewController: UIViewController , UITextFieldDelegate {
@IBOutlet weak var userMobileNoTextFiled: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
//ステップ2デリゲートを設定
userMobileNoTextFiled.delegate = self // setデリゲート}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
// guard let text = userMobileNoTextFiled.text else { return true }
// let newLength = text.count + string.count - range.length
// return newLength <= 10
// }
// STEP 3 call func
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let maxLength = 10 // set your need
let currentString: NSString = textField.text! as NSString
let newString: NSString =
currentString.replacingCharacters(in: range, with: string) as NSString
return newString.length <= maxLength
}
}
不要な文字列操作を回避するSwift 3.2+の代替手段を次に示します。この場合、最大長は10です。
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let text = textField.text ?? ""
return text.count - range.length + string.count <= 10
}
この手順では、まずviewdidloadでデリゲートテキストフィールドを設定します。
override func viewDidLoad() {
super.viewDidLoad()
textfield.delegate = self
}
uITextFieldDelegateを含めた後にshouldChangeCharactersInを追加します。
extension viewController: UITextFieldDelegate {
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let newLength = (textField.text?.utf16.count)! + string.utf16.count - range.length
if newLength <= 8 {
return true
} else {
return false
}
}
}
スイフト5
クレジット: http://www.swiftdevcenter.com/max-character-limit-of-uitextfield-and-allowed-characters-Swift/
最大文字長を設定するために1つ書くだけです
self.textField.maxLength = 10
詳細については ここをクリック
単に文字列の文字数で確認するだけです
class YorsClassName : UITextFieldDelegate {
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if textField.text?.count == 1 {
return false
}
return true
}
注:ここでは、textFieldで許可されているcharのみをチェックしました