簡體   English   中英

如果按下“退格”按鈕並且文本字段為空白並且在 Swift 4 中,我如何移動到以前的 UITextField?

[英]How can I move to the previous UITextField if the "Backspace" button is pressed and the text field is blank and in Swift 4?

我試圖弄清楚這一點。 當我使用下面的代碼時,我可以從一個文本字段移動到下一個文本字段並單擊“退格”按鈕,但僅當文本字段中有文本時。

我的問題:當文本字段為空白時,如何單擊“退格”按鈕並移至上一個文本字段?

第二個問題:如何消除UITextField上閃爍的藍線?

以下是我擁有的代碼。 任何幫助將不勝感激!

@objc func textFieldDidChange(textfield: UITextField) {
    let text = textfield.text!
    if text.utf16.count == 0 {
        switch textfield {
        case textField2:
            textField1.becomeFirstResponder()
            textField1.backgroundColor = UIColor.black
        case textField3:
            textField2.becomeFirstResponder()
            textField2.backgroundColor = UIColor.black
        case textField4:
            textField3.becomeFirstResponder()
            textField3.backgroundColor = UIColor.black
        case textField5:
            textField4.becomeFirstResponder()
            textField4.backgroundColor = UIColor.black
        case textField6:
            textField5.becomeFirstResponder()
            textField5.backgroundColor = UIColor.black
            textField6.resignFirstResponder()
            textField6.backgroundColor = UIColor.black
        default:
            break
        }
    }
    else if text.utf16.count == 1 {
        switch textfield {
        case textField1:
            textField1.backgroundColor = UIColor.black
            textField1.textColor = .white
            textField2.becomeFirstResponder()
            textField2.backgroundColor = UIColor.black
            textField2.textColor = .white
        case textField2:
            textField3.becomeFirstResponder()
            textField3.backgroundColor = UIColor.black
            textField3.textColor = .white
        case textField3:
            textField4.becomeFirstResponder()
            textField4.backgroundColor = UIColor.black
            textField4.textColor = .white
        case textField4:
            textField5.becomeFirstResponder()
            textField5.backgroundColor = UIColor.black
            textField5.textColor = .white
        case textField5:
            textField6.becomeFirstResponder()
            textField6.backgroundColor = UIColor.black
            textField6.textColor = .white
        case textField6:
            textField6.resignFirstResponder()
        default:
            break

        }
    }
}

您應該將UITextField子類化以實現deleteBackward()函數。 此外,您應該實現一個協議,該協議具有在調用deleteBackward()且文本為空時執行的函數。

免責聲明:此代碼的來源位於VENTokenField項目中。 它被轉換為Swift並由我調整。

class BackspaceTextField: UITextField {
    weak var backspaceTextFieldDelegate: BackspaceTextFieldDelegate?

    override func deleteBackward() {
        if text?.isEmpty ?? false {
            backspaceTextFieldDelegate?.textFieldDidEnterBackspace(self)
        }

        super.deleteBackward()
    }
}

protocol BackspaceTextFieldDelegate: class {
    func textFieldDidEnterBackspace(_ textField: BackspaceTextField)
}

不是單獨處理每個文本字段,而是在視圖控制器中創建一個文本字段數組,並在那里處理第一個響應者。 如果存在先前的視圖控制器,則將其設置為第一響應者(您不需要重新簽名任何內容,因為之前的響應者將在更改后自動重新簽名)。 如果它是數組中的第一個文本字段,則結束編輯。

class ViewController: UIViewController, BackspaceTextFieldDelegate {
    var textField1: BackspaceTextField!
    var textField2: BackspaceTextField!
    [...]

    var textFields: [BackspaceTextField] {
        return [textField1, textField2, [...]]
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        textFields.forEach { $0.backspaceTextFieldDelegate = self }
    }

    func textFieldDidEnterBackspace(_ textField: BackspaceTextField) {
        guard let index = textFields.index(of: textField) else {
            return
        }

        if index > 0 {
            textFields[index - 1].becomeFirstResponder()
        } else {
            view.endEditing(true)
        }
    }
}

關於閃爍的藍線,請使用tintColor:

textfield.tintColor = UIColor.black

您可以使用文本字段的背景顏色來隱藏它。

關於問題1:

更改@Jon提到的文本字段的色調顏色。

關於問題2:

我所做的是為TextFieldDelegate創建一個擴展。 在其中,我使用NotificationCenter.default作為需要在當前類中定義的函數創建了另一個警報功能。

extension UITextFieldDelegate {
    func deleteSelected(field: UITextField) {
        NotificationCenter.default.post(name: Notification.Name("deleteSelected"), object: field)
    }
}

請注意,為了使其正常工作,必須在按下刪除鍵時調用該函數。 這可以在您的UITextField的子類中完成,方法是:

override func deleteBackward() {
    super.deleteBackward()
    delegate?.deleteSelected(field: self)
}

最后,您需要通過在要對其執行操作的視圖中向該通知添加觀察者來偵聽事件。

NotificationCenter.default.addObserver(self, selector: #selector(checkForDelete(_ :)), name: Notification.Name("deleteSelected"), object: nil)

如果你還沒有定義checkForDelete(_ :),這就是我的樣子:

@objc func checkForDelete(_ notification: Notification) {
    if let field = notification.object as? MyTextField {
        if let textFound = field.text, !textFound.isEmpty {
            //  Do nothing extra
            print("Text found: \(textFound).")
        } else {
            //  Go to previous field
            guard let activeField = active(textField: field).field, let index = active(textField: field).index else {
                print("Field could not be determined")
                return
            }
            print("Going backwards")
            activeField.text = nil
            activeField.resignFirstResponder()
            activeField.stateOfTextField = .empty
            textFields[index == 0 ? 0 : index - 1].becomeFirstResponder()
            textFields[index == 0 ? 0 : index - 1].text = nil
        }
    }
}

else語句中的'Guard'確定當前活動的文本字段是什么,並返回索引(它們存儲在數組中),因此我們可以轉到前一個TextField(如果有的話)。

當您有四個文本字段 inputOne、inputTwo、inputThree、inputFour 時,創建 4 個 @IBOutlet like @IBOutlet weak var inputOne、@IBOutlet weak var inputOne、@IBOutlet weak var inputThree、@IBOutlet weak var inputFour

這很簡單,在 TextField 編輯開始時添加空格

如果用戶輸入諸如“1”到“9”之類的值,則下一個文本字段將成為第一響應者如果用戶點擊 backButton 如果文本字段包含值,則將其替換為空白,如果用戶點擊 backButton 如果文本字段包含空白,則前一個文本字段將成為第一響應者

只有我使用兩個 TextField 委托方法

  1. textFieldDidBeginEditing
  2. shouldChangeCharactersIn

func textFieldDidBeginEditing(_ textField: UITextField) {

    if(textField.text == ""){
        textField.text = " "
    } 

}

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

    let maxLength = 1
    let currentString: NSString = textField.text! as NSString
    let newString: NSString = currentString.replacingCharacters(in: range, with: string) as NSString
    if let char = string.cString(using: String.Encoding.utf8) {
        let isBackSpace = strcmp(char, "\\b")
        if (isBackSpace == -92 && textField.text == " ") {
            if(textField.tag == 0){
                self.focusOnTextField(selTextField:inputOne)
         
                return false
            }else if(textField.tag == 1){
                self.focusOnTextField(selTextField:inputOne)
                
                return false
            }else if(textField.tag == 2){
                self.focusOnTextField(selTextField:inputTwo)
                
                return false
            }else if(textField.tag == 3){
                self.focusOnTextField(selTextField:inputThree)
                
                return false
            }
        }
        else if (isBackSpace == -92 && textField.text != " ") {
            textField.text = " "
            
            return false
        }
        else {
            textField.text = textField.text?.replacingOccurrences(of:textField.text!, with:string)
        }
    }
    
    let newPosition = textField.endOfDocument
    textField.selectedTextRange = textField.textRange(from: newPosition, to: newPosition)
    if(textField.tag == 0){
        self.focusOnTextField(selTextField:inputTwo)
    } else if(textField.tag == 1){
        self.focusOnTextField(selTextField:inputThree)
    }else if(textField.tag == 2){
        self.focusOnTextField(selTextField:inputFour)
    }
    return newString.length <= maxLength
}
 
func focusOnTextField(selTextField:UITextField) {       
        selTextField.becomeFirstResponder()
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM