如何在Swift中限制UITextField中的某些字符?

7

我正在创建一款问答应用,启动时会要求输入用户名。我希望禁止使用像#$@!^&这些特殊字符(包括空格)。我看了这篇帖子(链接在此),但它完全是用Objective-C写的。提前感谢。


我已经添加了使用Swift的答案到原始问题中。 - Evdzhan Mustafa
8个回答

6

在这个例子中,基于使用扩展(extension),Swift 4 iOS 11.2.x测试一个字符串是否是有效的十六进制数。

extension String {

var containsValidCharacter: Bool {
    guard self != "" else { return true }
    let hexSet = CharacterSet(charactersIn: "1234567890ABCDEFabcdef")
    let newSet = CharacterSet(charactersIn: self)
    return hexSet.isSuperset(of: newSet)
  }
}

您可以像使用UITextFieldDelegate一样使用它。

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    return (string.containsValidCharacter)
}

虽然我在之前的帖子中读到CharacterSet不支持由多个Unicode.Scalar组成的字符,因此需要谨慎使用。


3

既然您明确要求使用Swift,我已经翻译了链接问题中的顶部答案。

let notAllowedCharacters = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.";

func textField(
    textField: UITextField,
    shouldChangeCharactersInRange range: NSRange,
    replacementString string: String)
    -> Bool
{
    let set = NSCharacterSet(charactersInString: notAllowedCharacters);
    let inverted = set.invertedSet;

    let filtered = string
        .componentsSeparatedByCharactersInSet(inverted)
        .joinWithSeparator("");
    return filtered != string;

}

1
无法改掉那个分号的习惯。 - Dale

2
internal func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool{
     if let text = string{
           if text == "#" || text == "$" || text == "!"{ \\and so on
              return false
           }
     }
     return true
}

假设替换字符串是单个字符,但在粘贴字符串时它可以是更多字符。 - Dale

1

这是一个关于使用扩展来检测字符串是否为有效十六进制数的例子,基于 Swift 4 和 iOS 11.2.x。

扩展 String {

var containsValidCharacter: Bool {
    guard self != "" else { return true }
    let hexSet = CharacterSet(charactersIn: "1234567890ABCDEFabcdef")
    let newSet = CharacterSet(charactersIn: self)
    return hexSet.isSuperset(of: newSet)
  }
}

你像使用UITextFieldDelegate一样使用它。

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    return (string.containsValidCharacter)
}

1

Swift 2.3

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {

        let characters = ["#", "$", "!", "&","@"]
        for character in characters{
            if string == character{
                print("This characters are not allowed")
                return false
            }
        }
}

假设替换字符串是单个字符,但如果粘贴,则可以是更多字符。 - Dale

1
这可能是限制空格最强大的方法。使用此方法,用户将无法粘贴/输入空格。
以下是使用Swift 3实现的方法。
在Swift文件中添加下面提到的扩展程序片段。
extension String {

var containsWhitespace: Bool {
    for scalar in unicodeScalars {
        switch scalar.value {
        case 0x20:
            return true
        default:
            continue
        }
    }
    return false
  }
}

在你的ViewController Swift文件中,从Storyboard拖出Editing Changed实例和一个UITextFieldReferencing Outlet,如下图所示:

enter image description here

请按以下方式使用拖动的实例:

引用输出口为:

@IBOutlet weak var textField: UITextField!

并且编辑已更改为:

 @IBAction func textChanged(_ sender: UITextField) {
    if (textField.text!.containsWhitespace) == true {
        print("Restrict/Delete Whitespace")
        emailField.deleteBackward()
    } else {
        print("If Its not Whitespace, Its allowed.")
    }
}

这将在用户尝试输入/粘贴时立即检测和删除空格。

0

Swift: 3 和不同的方法:

在您的 viewDidLoad 中为文本字段更改添加目标函数:

    override func viewDidLoad() {
    super.viewDidLoad()
textField.addTarget(self, action: #selector(ViewController.textFieldDidChange(textField:)), for: UIControlEvents.editingChanged)
 }

在目标函数中,只需检测输入的字符并将其替换为空格。我已经测试过它,可以防止用户在文本字段中输入任何不希望出现的字符。
 func textFieldDidChange(textField: UITextField) {

    if let textInField = textField.text{
        if let lastChar = textInField.characters.last{

            //here include more characters which you don't want user to put in the text field
            if(lastChar == "*")
            {

                textField.text  = textInField.substring(to: textInField.index(before: textInField.endIndex))

            }
        }
    }

}

0

继@Evdzhan Mustafa所说的,你需要添加一个返回语句以防字符串为空。如果没有它,你将无法删除你的文本。修改后的代码如下:

Swift 3版本

let notAllowedCharacters = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.";

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    if string.isEmpty{
        return true
    }

    print("String: \(string)")
    let set = NSCharacterSet(charactersIn: notAllowedCharacters);
    let inverted = set.inverted;

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

去掉那些分号。 - Dale
有个想法,觉得正则表达式可能是一种更简单的过滤字符的方法。于是在这里改用了正则表达式来处理模型。结果感觉更加灵活多了。 - Jeff Muir
1
Swift 3正则表达式示例检查0-9: if !(string.range(of:"^[0-9]+$", options: .regularExpression) != nil) { valid = false }检查0-9,A-Z: if !(string.range(of:"^[0-9A-Z]+$", options: .regularExpression) != nil) { valid = false } - Jeff Muir

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接