Swift 手机号复制粘贴的处理

77 阅读2分钟

目录

  • 需求:手机号输入在输入的时候可以复制进去:比如:+86 185006528811850065288186 1850065288118500\n652881
  • 思路:复制信息拦截做处理,处理后再进行正则、长度等校验
  • 代码实现
    • 复制拦截
    • 具体代码实现

一、复制拦截

1.1、这里以UITextFiled为例

创建继承于UITextField的类,暂且命名为JKPastedTextField,重写paste方法

import UIKit

public class JKPastedTextField: UITextField {
    // 是否正在复制
    public var isPasting = false
    public override func paste(_ sender: Any?) {
        super.paste(sender)
        isPasting = true
    }
}
1.2、监听代理方法:UITextFieldDelegate
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    if infoTextField.isPasting {
        debugPrint("✅复制----:\(string)")
    } else {
        debugPrint("💣不是复制----:\(string)")
    }
    return textField.jk.inputRestrictions(shouldChangeTextIn: range, replacementText: string, maxCharacters: maxCharacters, regex: "^[A-Za-z0-9]+$", lenghType: lenghType, isRemovePasteboardNewlineCharacters: true)
}

提示:inputRestrictions方法是在库JKSwiftExtensionUITextField+Extension.swift的扩展方法,专门用来处理输入长度输入长度超出截取正则判断复制粘贴等逻辑的方法

二、具体代码实现

- 2.1、手机号+86、86、换行\n、空格等处理
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    var content = string
    if phoneNumberTextField.isPasting {
        debugPrint("✅复制----:\(string)")
        if content.jk.isHasPrefix(prefix: "+86") {
            content = content.jk.removeSomeStringUseSomeString(removeString: "+86", replacingString: "")
        }
        if content.jk.isHasPrefix(prefix: "86") {
            content = content.jk.removeSomeStringUseSomeString(removeString: "86", replacingString: "")
        }
        content = content.jk.removeAllLineAndSapcefeed
    } else {
        debugPrint("💣不是复制----:\(string)")
    }
    return textField.jk.inputRestrictions(shouldChangeTextIn: range, replacementText: content, maxCharacters: maxCharacters, regex: "^[A-Za-z0-9]+$", lenghType: lenghType, isRemovePasteboardNewlineCharacters: true)
}
2.2、具体的细节处理,核心的内容还在扩展里面的,下面只是部分代码,具体的请到 JKSwiftExtension里面查看
// MARK: 限制字数的输入(提示在:- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string; 里面调用)
/// 限制字数的输入
/// - Parameters:
///   - range: 范围
///   - text: 输入的文字
///   - maxCharacters: 限制字数
///   - regex: 可输入内容(正则)
///   - isInterceptString: 复制文字进来,在字数限制的情况下,多余的字体是否截取掉,默认true
///   - isRemovePasteboardNewlineCharacters: 复制的内容是否移除前后的换行符
///   - isMarkedTextRangeCanInput: 高亮状态,原始数据如果小于限制字数,默认不可以继续输入
/// - Returns: 返回是否可输入
///
/// 提示:注入想要处理复制的内容:使用的UITextField继承JKPastedTextField,也可以自己按照我的这种方式自己个性化处理
func inputRestrictions(shouldChangeTextIn range: NSRange, replacementText text: String, maxCharacters: Int, regex: String?, isInterceptString: Bool = true, lenghType: StringTypeLength = .count, isRemovePasteboardNewlineCharacters: Bool = false, isMarkedTextRangeCanInput: Bool = false) -> Bool {
    guard !text.isEmpty else {
        return true
    }
    guard let oldContent = self.base.text else {
        return false
    }
    // 输入新的内容
    var inputingContent = text
    if let pastedTextField = self.base as? JKPastedTextField, isRemovePasteboardNewlineCharacters, pastedTextField.isPasting {
        // 复制内容,只处理前后的空格和换行
        inputingContent = inputingContent.jk.removeAllLineAndSapcefeed
        pastedTextField.isPasting = false
        if let weakRegex = regex, !JKRegexHelper.match(inputingContent, pattern: weakRegex) {
            return false
        }
        let remainingLength = maxCharacters - oldContent.jk.typeLengh(lenghType)
        // 可以插入字符串
        let endString = getInputText(inputingContent: inputingContent, remainingLength: remainingLength, lenghType: lenghType)
        let newString = oldContent.jk.insertString(content: endString, locat: range.location)
        self.base.text = newString
        self.base.sendActions(for: .editingChanged)
        // 异步改变
        JKAsyncs.asyncDelay(0.1) {} _: {
            let endPosition = self.base.position(from: elf.base.beginningOfDocument, offset: range.location + endString.count)
            if let endPosition = endPosition {
                self.base.selectedTextRange = self.base.textRange(from: endPosition, to: endPosition)
            }
        }
        return false
    }
}

demo