Robię ten ekran OTP, ale mam trochę połowu,

Robię ten ekran OTP z wiązką Uitextfield i robię logikę, ale po prostu nie mogę usunąć z Num w polu TextField, który robię

TextField nie usuwa, gdy wypełniam pierwsze 2 mojego num, nawet ja pressess Backbutton nie działa ..... ale będzie działać, gdy wypełniam całą liczbę tekstów, w moim przypadku jest sześć.

Muszę więc wypełnić wszystkie sześć liczby i mogę usunąć numer z pola tekstowego, nie działa, jeśli tylko połowa wypełnia pola tekstowa.

Heres mój kod:

 func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    
    if ((textField.text?.count)! < 1) && (string.count > 0) {
        if textField == txtOTP1 {
            txtOTP2.becomeFirstResponder()
        }
        if textField == txtOTP2 {
            txtOTP3.becomeFirstResponder()
        }
        if textField == txtOTP3 {
            txtOTP4.becomeFirstResponder()
        }
        if textField == txtOTP4 {
            txtOTP5.becomeFirstResponder()
        }
        if textField == txtOTP5{
            txtOTP6.becomeFirstResponder()
        }
        if textField == txtOTP6{
            txtOTP6.resignFirstResponder()
        }
        
        textField.text = string
        return false
    }else if ((textField.text?.count)! >= 1) && (string.count == 0) {
        if textField == txtOTP2{
            txtOTP1.becomeFirstResponder()
        }
        if textField == txtOTP3{
            txtOTP2.becomeFirstResponder()
        }
        if textField == txtOTP4{
            txtOTP3.becomeFirstResponder()
        }
        if textField == txtOTP5{
            txtOTP4.becomeFirstResponder()
        }
        if textField == txtOTP6{
            txtOTP5.becomeFirstResponder()
        }
        if textField == txtOTP1{
            txtOTP1.resignFirstResponder()
        }
    
        textField.text = ""
        return false
    }
    else if (textField.text?.count)! >= 1 {

        
        textField.text = string
        return false
    }
    
    return true
}

To jest kod, którego używam, aby zrobić Logikę OTP Uitextfield ...... proszę mi powiedzieć, że wiem, że coś nie tak z moim logiką, dzięki.

Według producenta powiedział, że naprawić ten problem, muszę tylko "ustawić interakcje użytkownika dla TextField False i wykonać pierwszy textField First Responder", myślę, że po prostu zrobiłem to, ale może zrobiłem to źle ....

Naprawdę muszę naprawić tego facetów, dzięki.

2
afi permana 20 lipiec 2020, 22:48

1 odpowiedź

Najlepsza odpowiedź

Zamiast naprawić ten kod, wolę utworzyć niestandardowe pole tekstowe, które informowałyby, gdy zostanie naciśnięty klawisz Usuńbackward. Więc pierwsza podklasa a Uitextfield:


import UIKit
class SingleDigitField: UITextField {
    // create a boolean property to hold the deleteBackward info
    var pressedDelete = false
    // customize the text field as you wish 
    override func willMove(toSuperview newSuperview: UIView?) {
        keyboardType = .numberPad
        textAlignment = .center
        backgroundColor = .blue
        isSecureTextEntry = true
        isUserInteractionEnabled = false
    }
    // hide cursor
    override func caretRect(for position: UITextPosition) -> CGRect { .zero }
    // hide selection
    override func selectionRects(for range: UITextRange) -> [UITextSelectionRect] { [] }
    // disable copy paste
    override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool { false }
    // override deleteBackward method, set the property value to true and send an action for editingChanged
    override func deleteBackward() {
        pressedDelete = true
        sendActions(for: .editingChanged)
    }
}

Teraz w Twojej ViewController:

import UIKit

class ViewController: UIViewController {
    // connect the textfields outlets
    @IBOutlet weak var firstDigitField: SingleDigitField!
    @IBOutlet weak var secondDigitField: SingleDigitField!
    @IBOutlet weak var thirdDigitField: SingleDigitField!
    @IBOutlet weak var fourthDigitField: SingleDigitField!
    override func viewDidLoad() {
        super.viewDidLoad()
        // add a target for editing changed for each field
        [firstDigitField,secondDigitField,thirdDigitField,fourthDigitField].forEach {
            $0?.addTarget(self, action: #selector(editingChanged), for: .editingChanged)
        }
        // make the firsDigitField the first responder
        firstDigitField.isUserInteractionEnabled = true
        firstDigitField.becomeFirstResponder()
    }
    // here you control what happens to each change that occurs to the fields
    @objc func editingChanged(_ textField: SingleDigitField) {
        // check if the deleteBackwards key was pressed
        if textField.pressedDelete {
            // reset its state
            textField.pressedDelete = false
            // if the field has text empty its content
            if textField.hasText {
                textField.text = ""   
            } else {
                // otherwise switch the field, resign the first responder and activate the previous field and empty its contents
                switch textField {
                case secondDigitField, thirdDigitField, fourthDigitField:
                    textField.resignFirstResponder()
                    textField.isUserInteractionEnabled = false
                    switch textField {
                    case secondDigitField:
                        firstDigitField.isUserInteractionEnabled = true
                        firstDigitField.becomeFirstResponder()
                        firstDigitField.text = ""
                    case thirdDigitField:
                        secondDigitField.isUserInteractionEnabled = true
                        secondDigitField.becomeFirstResponder()
                        secondDigitField.text = ""
                    case fourthDigitField:
                        thirdDigitField.isUserInteractionEnabled = true
                        thirdDigitField.becomeFirstResponder()
                        thirdDigitField.text = ""
                    default:
                        break
                    }
                default: break
                }
            }
        }
        // make sure there is only one character and it is a number otherwise delete its contents
        guard textField.text?.count == 1, textField.text?.last?.isWholeNumber == true else {
            textField.text = ""
            return
        }
        // switch the textField, resign the first responder and make the next field active
        switch textField {
        case firstDigitField, secondDigitField, thirdDigitField:
            textField.resignFirstResponder()
            textField.isUserInteractionEnabled = false
            switch textField {
            case firstDigitField:
                secondDigitField.isUserInteractionEnabled = true
                secondDigitField.becomeFirstResponder()
            case secondDigitField:
                thirdDigitField.isUserInteractionEnabled = true
                thirdDigitField.becomeFirstResponder()
            case thirdDigitField:
                fourthDigitField.isUserInteractionEnabled = true
                fourthDigitField.becomeFirstResponder()
            default: break
            }
        case fourthDigitField:
            fourthDigitField.resignFirstResponder()
        default: break
        }
    }
}

Projekt XCode 12

0
Leo Dabus 21 lipiec 2020, 04:08