SwiftUI

SwiftUI UITextField 只输入数字

struct CustomTextfield: UIViewRepresentable {

    @Binding var text: String

    func makeUIView(context: Context) -> UITextField {
        let view = UITextField()
        view.setLeftPaddingPoints(10)
        view.isUserInteractionEnabled = true
        view.backgroundColor = .white
        view.layer.borderColor = uiColorE5E5E5.cgColor
        view.layer.borderWidth = 1
        view.layer.cornerRadius = 4
        view.font = UIFont.systemFont(ofSize: 16, weight: .bold)
        view.textColor = uiColorD57B21
        view.delegate = context.coordinator
        view.keyboardType = UIKeyboardType.numberPad

        return view
    }

    func updateUIView(_ uiView: UITextField, context: Context) {
        uiView.text = text
    }

    func makeCoordinator() -> CustomTextfield.Coordinator {
        Coordinator(self)
    }

    class Coordinator: NSObject, UITextFieldDelegate {
        var control: CustomTextfield

        init(_ control: CustomTextfield) {
            self.control = control
        }

        func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
            self.control.text = textField.text!
            return true
        }

     func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        // 获取输入的文本,移除向输入框中粘贴文本时,系统自动加上的空格(iOS11上有该问题)
        let new = string.replacingOccurrences(of: " ", with: "")
        // 获取编辑前的文本
        var old = NSString(string: textField.text ?? "")
        // 获取编辑后的文本
        old = old.replacingCharacters(in: range, with: new) as NSString
        // 获取数字的字符集
        let number = CharacterSet(charactersIn: "0123456789")
        // 判断编辑后的文本是否全为数字
        if old.rangeOfCharacter(from: number.inverted).location == NSNotFound {
            // number.inverted表示除了number中包含的字符以外的其他全部字符
            // 如果old中不包含其他字符,则格式正确
            // 允许本次编辑
            textField.text = old as String
            // 移动光标的位置
            DispatchQueue.main.async {
                let beginning = textField.beginningOfDocument
                let position = textField.position(from: beginning, offset: range.location + new.count)!
                textField.selectedTextRange = textField.textRange(from: position, to: position)
            }
        }
        return false
    }

}

下面的例子只能输入小数,比如38.12211

struct gpsTextfield: UIViewRepresentable {
    @Binding var text: String

    func makeUIView(context: Context) -> UITextField {
        let textfield = UITextField()
        textfield.keyboardType = .numberPad
        textfield.textAlignment = .left
        textfield.delegate = context.coordinator
        textfield.text = text
        textfield.backgroundColor = uiColorF9F9F9
        textfield.layer.borderColor = uiColorC5C5C5.cgColor
        textfield.layer.cornerRadius = 4
        textfield.layer.borderWidth = 1
        textfield.font = UIFont.init(name: "KozGoPro-Bold", size: 16)
        textfield.setLeftPaddingPoints(10)

        return textfield
    }

    func updateUIView(_ uiView: UITextField, context: Context) {
        uiView.text = text
    }

    func makeCoordinator() -> gpsTextfield.Coordinator {
        Coordinator(self)
    }

    class Coordinator: NSObject, UITextFieldDelegate {
        var control: gpsTextfield

        init(_ control: gpsTextfield) {
            self.control = control
        }

        func textFieldDidChangeSelection(_ textField: UITextField) {
            self.control.text = textField.text!
        }

        func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
            NotificationCenter.default.post(name: .kmpointEditBegin, object: nil, userInfo: nil)
            return true
        }

        func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
            self.control.text = textField.text!
            textField.endEditing(true)
            return true
        }

        func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
            // 获取输入的文本,移除向输入框中粘贴文本时,系统自动加上的空格(iOS11上有该问题)
            let new = string.replacingOccurrences(of: " ", with: "")
            // 获取编辑前的文本
            var old = NSString(string: textField.text ?? "")
            // 获取编辑后的文本
            old = old.replacingCharacters(in: range, with: new) as NSString
            // 获取数字的字符集
            let number = CharacterSet(charactersIn: "0123456789.")
            // 判断编辑后的文本是否全为数字
            if old.rangeOfCharacter(from: number.inverted).location == NSNotFound && CommonUtil.checkLocationInput(gpsString: old as String) {
                // number.inverted表示除了number中包含的字符以外的其他全部字符
                // 如果old中不包含其他字符,则格式正确
                // 允许本次编辑
                textField.text = old as String
                // 移动光标的位置
                DispatchQueue.main.async {
                    let beginning = textField.beginningOfDocument
                    let position = textField.position(from: beginning, offset: range.location + new.count)!
                    textField.selectedTextRange = textField.textRange(from: position, to: position)
                }
            }
            return false
        }
    }
}
    // 判断小数点个数
public class func checkLocationInput(gpsString: String) -> Bool {
        
        var num = 0
        for ch in gpsString
        {
            if ch == "." {
                num = num + 1
            }
        }
        if num > 1 {
            return false
        }
        return true
    }
}