美文网首页
UITextfield常用输入限制

UITextfield常用输入限制

作者: 霸哥终结者 | 来源:发表于2022-07-26 10:23 被阅读0次

背景

在日常需求中,UITextField输入框需要做一些输入限制,防止用户乱输入,一般有两种方式,一种是在输入时输入非法字符无效,另一种是输入完成后,提示用户输入有误;这两种各有各的用处, 前一种是硬性规定那些不能输入,后一种则是对整个字符串进行规则(正则,数量等)校验。 下面介绍通过提取用户已完成的文本加上RxSwift监听机制完成输入限制的方法。

实现

// MARK: - 输入框扩展
extension UITextField {
    
    /// 过滤预输入后的普通文本
    var normalText: String? {
        if let textRange = markedTextRange {
            if textRange.isEmpty {
                return text
            } else {
                if var text = text {
                    let location = self.offset(from: self.beginningOfDocument, to: textRange.start)
                    let length = self.offset(from: textRange.start, to: textRange.end)
                    let nsRange = NSRange(location: location, length: length)
                    if let range = Range.init(nsRange, in: text) {
                        text.replaceSubrange(range, with: "")
                        return text
                    }
                }
                return text
            }
        } else {
            return text
        }
    }
    
    /// 更新文本(不一样才更新)
    func updateTextIfNeed(_ text: String?) {
        if normalText != text {
            self.text = text
        }
    }
    
    /// 限制输入字数,0为不限制
    func limit(_ count: Int) {
        self.rx.controlEvent(.editingChanged).bind { [weak self] _ in
            guard let self = self else { return }
            if let normalText = self.normalText, normalText.count > count {
                let index = normalText.index(normalText.startIndex, offsetBy: count)
                let newText = String(normalText[..<index])
                self.updateTextIfNeed(newText)
            }
        }.disposed(by: rx.disposeBag)
    }
    
    /// 限制中文输入
    func limitChinese() {
        // 名字中文输入限制
        self.rx.text.bind { [weak self] _ in
            guard let self = self else { return }
            
            // 1. 获取到已完成的文本
            if let text = self.normalText {
                // 定义替换后的文本
                var newText = ""
                // 2. 过滤非中文
                newText = text.filter({ c in
                    let isChinese = "\u{4e00}" <= c && c <= "\u{9fa5}"
                    return isChinese
                })
                // 3. 对比过滤后的文本是否不一致,不一致则更新
                self.updateTextIfNeed(newText)
            }
        }.disposed(by: rx.disposeBag)
    }
    
    /// 限制输入字符
    func limitCharaters(_ chars: Set<Character>) {
        self.rx.text.bind { [weak self] _ in
            guard let self = self else { return }
            // 1. 获取到已完成的文本
            if let text = self.normalText {
                // 定义替换后的文本
                var newText = ""
                // 2. 过滤非中文
                newText = text.filter({ c in
                    return chars.contains(c)
                })
                // 3. 对比过滤后的文本是否不一致,不一致则更新
                self.updateTextIfNeed(newText)
            }
        }.disposed(by: rx.disposeBag)
        
    }
    
    /// 替换文本
    func replace(orgin: String, new: String) {
        self.rx.text.bind { [weak self] _ in
            guard let self = self else { return }
            if let text = self.normalText {
                let newText = text.replacingOccurrences(of: orgin, with: new)
                self.updateTextIfNeed(newText)
            }
        }.disposed(by: rx.disposeBag)
    }
}

相关文章

网友评论

      本文标题:UITextfield常用输入限制

      本文链接:https://www.haomeiwen.com/subject/vphoirtx.html