简体   繁体   English

斯威夫特3:在修改时附加到UITextField

[英]Swift 3: Append to UITextField while Editing Changed

Probably a simple one although no answers updated for Swift 3. 可能很简单,尽管Swift 3的答案没有更新。

How can I append characters to a UITextField while the textfield is being edited? 如何在编辑文本字段时将字符追加到UITextField? The characters should be appended while the user types not after the editing ends. 在用户键入内容时,应在编辑结束后添加字符。

For example: 例如:

User types: 1
Field Updates: 1 kg

User types 123
Field Updates: 123 kg

Was trying to tackle this using EditingChanged IBActions but how can I stop the value from appending "kg" for each new character that is typed? 正在尝试使用EditingChanged IBActions解决此问题,但是如何停止为键入的每个新字符附加“ kg”值呢?

Example "1 kg 2 kg 3 kg" 

Try this way it may help you out. 尝试这种方式可能会帮助您。

  1. Add target for textfield on text is being editing 在文本上为文本字段添加目标正在编辑

     textField.addTarget(self, action: #selector(self.textFieldDidChange), for: .editingChanged) 
  2. In Observer method try the following way 在观察者方法中尝试以下方法

     func textFieldDidChange(textfield: UITextField) { var text = textField.text?.replacingOccurrences(of: " KG", with: "") text = text! + " KG" textField.text = text print("Text changed") } 

You want the UITextFieldDelegate method 您需要UITextFieldDelegate方法

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool

I should warn you that this is incredibly irritating to implement because of the way Swift handles Strings. 我应该警告您,由于Swift处理字符串的方式,实现起来非常烦人。 Its usually better to just cast the text to NSString (which is UTF16) and deal with the range that way. 通常最好将文本强制转换为NSString(即UTF16)并以这种方式处理范围。 However if you are just doing numbers and can live with a fixed decimal place the case is much easier to handle. 但是,如果您只是在做数字,并且可以使用固定的小数位,则该情况更容易处理。 Keep a custom number that represents your "real number" and just update the field to reflect your formatted number. 保留一个代表您的“实数”的自定义数字,然后更新该字段以反映您的格式化数字。 Since you only allow digits there are finitely many cases to handle (this code will not handle copy/paste). 由于只允许数字,因此只能处理多种情况(此代码将不处理复制/粘贴)。

You must set the textfield delegate and keyboard (to numeric) in the storyboard. 您必须在情节提要中设置文本字段委托和键盘(为数字)。

    class ViewController: UIViewController{
        @IBOutlet weak var textField: UITextField!
        fileprivate let digits: Set<String> = ["0","1","2","3","4","5","6","7","8","9"]
        fileprivate let decimalPlaces = 2
        fileprivate let suffix = " kg"
        fileprivate lazy var formatter: NumberFormatter = {
            let formatter = NumberFormatter()
            formatter.numberStyle = .decimal
            formatter.minimumFractionDigits = self.decimalPlaces
            formatter.maximumFractionDigits = self.decimalPlaces
            formatter.locale = NSLocale.current
            return formatter
        }()
        fileprivate var amount: Int = 0

        override func viewDidLoad() {
            super.viewDidLoad()

        }
    }

    extension ViewController: UITextFieldDelegate {
        func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

            if digits.contains(string) {
                amount *= 10
                amount += Int(string)!
            } else if string == "" {
                amount /= 10
            }

            guard amount > 0 else {
                textField.text = ""
                return false
            }

            let digitsAfterDecimal = formatter.maximumFractionDigits
            var value = Double(amount)
            for _ in 0..<digitsAfterDecimal {
                value /= 10
            }
            textField.text = formatter.string(from: NSNumber(value: value))! + suffix

            return false
        }

    }

Use UITextFieldDelegate's function: 使用UITextFieldDelegate's函数:

public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool // return NO to not change text

You'll have to combine the text from the textfield.text and string parameter from this function using the range parameter to get the string To Be formed on textfield while you type/paste/clear based on range. 您必须使用range参数将textfield.text中的文本与此函数中的string参数结合使用,以在基于范围键入/粘贴/清除时获取要在textfield上形成的字符串。

Keep track on range.length as it always gives the count of string being deleted/cleared and is 0 when you enter text. 跟踪range.length,因为它始终会给出要删除/清除的字符串的计数,并且在输入文本时为0。 And range.location gives the position of edit. range.location给出了编辑的位置。

Then you can set the formed string to textfield.text and return false Remember - return false and not true 然后,您可以将形成的字符串设置为textfield.text并返回false 记住-返回false而不是true

Conform the textfield delegate to the controller and try this solution. 使文本字段委托符合控制器,然后尝试此解决方案。

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    if string == "" {
        // handle backspace scenario here
      return true
    } else if var textString = textField.text {
        let unitString = "kg"
        if textString.contains(unitString) {
            textString = textString.replacingOccurrences(of: unitString, with: "")
            textString += string + unitString
            textField.text = textString
        } else {
            textField.text = string + unitString
        }
        return false
    }
    return true
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM