如何使用texfield扩展来限制用户输入特殊字符?

时间:2017-10-27 12:07:37

标签: ios swift xcode uitextfield

我想使用UITextField扩展来限制用户不要输入特殊字符。我使用下面的代码,但是UItextfield不允许我定义商店属性。所以我不知道在哪里定义特殊的字符集。

extension UITextField:UITextFieldDelegate {


    var allowSpecialCharecters:Bool {
        get {
            return self.allowSpecialCharecters
        }
        set {
           self.allowSpecialCharecters = newValue
        }
    }



    public func shouldChangeText(in range: UITextRange, replacementText text: String) -> Bool {


        if !allowSpecialCharecters {

            let set = NSCharacterSet(charactersIn: notAllowedCharacters);
            let inverted = set.inverted;

            let filtered = text.components(separatedBy: inverted).joined(separator: "")
            print("String Filtered: \(filtered)")
            return filtered != text;

        } else {
            return true
        }

    }
}

2 个答案:

答案 0 :(得分:0)

首先,使用UITextFieldDelegate的特定方法允许用户输入所需的字符:func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool

换句话说,通过实施此方法,您可以控制用户可以输入的字符,数字...... 以下是我用几个例子制作它的方法:

 func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    guard let text = textField.text else { return true }
    let candidate = (text as NSString).replacingCharacters(in: range, with: string)
    switch textField.tag {
    //Restrict to only have 2 number digits and max 23 for hours for UITextfields having tags 1, 3, 5 and 7
    case 1, 3, 5, 7:
        return textField.hasHourPattern(in: candidate, range: NSRange(location: 0, length: candidate.characters.count))
    //Restrict to only have 2 number digits and max 59 for minutes fr UITextFields having tags with 2, 4, 6 and 8
    case 2, 4, 6, 8:
        return textField.hasMinutePattern(in: candidate, range: NSRange(location: 0, length: candidate.characters.count))
    //Restrict to have 3 digits max for interger part then . and 2 digits for decimal part for UITextField having tag 9 
    case 9:
        return textField.hasTauxPattern(in: candidate, range: NSRange(location: 0, length: candidate.characters.count))
    default:
        return true
    }
}

然后,我扩展UITextField类以创建我的3个函数,以使用正则表达式检查输入表达式。我控制输入的表达式是否与特定模式匹配:

extension UITextField {
// Patterns function
// If has hour pattern : 0 to 23 include

  func hasHourPattern(in string: String, options: NSRegularExpression.MatchingOptions = [], range: NSRange) -> Bool {
    let regex = try? NSRegularExpression(pattern: "^(?:[0-9]|0[0-9]|1[0-9]|2[0-3]|)$", options: [])
    return regex?.firstMatch(in: string, options: [], range: NSRange(location: 0, length: string.characters.count)) != nil
  }

// If has minute pattern : 0 to 59 include

  func hasMinutePattern(in string: String, options: NSRegularExpression.MatchingOptions = [], range: NSRange) -> Bool {
    let regex = try? NSRegularExpression(pattern: "^(?:[0-9]|0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|)$", options: [])
    return regex?.firstMatch(in: string, options: [], range: NSRange(location: 0, length: string.characters.count)) != nil
  }

// If has taux pattern : 3 decimals . and 2 decimals

  func hasTauxPattern(in string: String, options: NSRegularExpression.MatchingOptions = [], range: NSRange) -> Bool {
    let regex = try? NSRegularExpression(pattern: "^\\d{0,3}(\\.\\d{0,2})?$", options: [])
    return regex?.firstMatch(in: string, options: [], range: NSRange(location: 0, length: string.characters.count)) != nil
  }
  ...//Create whatever function to check a pattern you want
}

此外,您还可以使用名为keyboardType的UITextfield属性,通过显示所需的键盘类型来指示您想要的字符类型。

答案 1 :(得分:0)

当心 IDIOCY 之间的区别

func textView(_ textView: UITextView,
       shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool

override func shouldChangeText(in range: UITextRange,
       replacementText text: String) -> Bool

第二个是内部UITextInput类的函数。

愚蠢的是,Xcode会自动为您完成“错一”。

该错误的功能不起作用,也不是UITextView的委托。

第一个是UITextViewDelegate。第一个是您想要的。

import UIKit
class Example: UITextView, UITextViewDelegate {

    override func .. init {
        super.delegate = self
    }

    func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        print("This works. Correct delegate function.")
        return true
    }

    // XCODE GIVES YOU THE FOLLOWING AS AN AUTOCOMPLETE:
    // IT IS TOTALLY WRONG:
    override func shouldChangeText(in range: UITextRange, replacementText text: String) -> Bool {
        print("Irrelevant badly named function. You will never see this.")
        return super.shouldChangeText(in: range, replacementText: text)
    }
}