简体   繁体   中英

UITextfield isBecomeFirstResponder not working in @IBDesignable of UIView

I am trying to make OTP Pin view and created everything and works well except textfield not moving automatically.

class OTPTextField: UITextField {
    var previousTextField: UITextField?
    var nextTextFiled: UITextField?
    
    override func deleteBackward() {
        text = ""
        previousTextField?.becomeFirstResponder()
    }
}
@IBDesignable public class OTPView : UIView{
    
    var textFieldArray = [OTPTextField]()
   
    @IBInspectable public var numberOfDots : Int = 4{
        didSet{
            setUpView()
        }
    }
    @IBInspectable public var bottomLineColor : UIColor = .white{
        didSet{
            setUpView()
        }
    }
    @IBInspectable public var stackViewSpacing : CGFloat = 10{
        didSet{
            setUpView()
        }
    }
   
    override init(frame: CGRect) {
         super.init(frame: frame)
            setUpView()
     }

     required init?(coder aDecoder: NSCoder) {
         super.init(coder: aDecoder)
         setUpView()
     }
    public override func layoutSubviews() {
        super.layoutSubviews()
    }
    fileprivate func setUpView(){
        let stackView = UIStackView()
        stackView.axis = .horizontal
        stackView.backgroundColor = .clear
        stackView.isUserInteractionEnabled = true
        stackView.translatesAutoresizingMaskIntoConstraints = false
//        stackView.alignment = .fill
        stackView.distribution = .fillEqually
        stackView.spacing = CGFloat(stackViewSpacing)
        self.addSubview(stackView)
        
        NSLayoutConstraint.activate([
            stackView.centerYAnchor.constraint(equalTo: self.centerYAnchor, constant: 0),
            stackView.centerXAnchor.constraint(equalTo: self.centerXAnchor, constant: 0),
            stackView.heightAnchor.constraint(equalTo: self.heightAnchor, multiplier: 1),
            stackView.widthAnchor.constraint(equalTo: self.widthAnchor, multiplier: 1)
        ])

        setTextFields(stackView: stackView)
    }
    private func setTextFields(stackView : UIStackView) {
        
        for i in 0..<numberOfDots {
            let field = OTPTextField()
            textFieldArray.append(field)
            stackView.addArrangedSubview(field)
            field.delegate = self
            field.backgroundColor = .clear
            field.textAlignment = .center
            field.keyboardType = .numberPad
            field.addBottomBorderView(lineColor: bottomLineColor)
            i != 0 ? (field.previousTextField = textFieldArray[i-1]) : ()
            i != 0 ? (textFieldArray[i-1].nextTextFiled = textFieldArray[i]) : ()
            
        }
    }
    
}
extension OTPView: UITextFieldDelegate {
    public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        guard let field = textField as? OTPTextField else {
            return true
        }
        if !string.isEmpty {
            field.text = string
            field.resignFirstResponder()
            field.nextTextFiled?.becomeFirstResponder()
            return true
        }
        return true
    }
}


extension UITextField {
    func addBottomBorder(){
        let bottomLine = CALayer()
        bottomLine.frame = CGRect(x: 0, y: self.frame.size.height - 1, width: self.frame.size.width, height: 1)
        bottomLine.backgroundColor = UIColor.white.cgColor
        borderStyle = .none
        layer.addSublayer(bottomLine)
    }
    func addBottomBorderView(lineColor : UIColor) {
        var bottomBorder = UIView()
        //MARK: Setup Bottom-Border
        self.translatesAutoresizingMaskIntoConstraints = false
        bottomBorder = UIView.init(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
        bottomBorder.backgroundColor = lineColor
        bottomBorder.translatesAutoresizingMaskIntoConstraints = false
        addSubview(bottomBorder)
        //Mark: Setup Anchors
        bottomBorder.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
        bottomBorder.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
        bottomBorder.rightAnchor.constraint(equalTo: rightAnchor).isActive = true
        bottomBorder.heightAnchor.constraint(equalToConstant: 1).isActive = true // Set Border-Strength
       }
}

Yes Need to remove all created previous fileds from array and from your UIStackView

 private func setTextFields() {
        self.removeFullyAllArrangedSubviews()
        textFieldArray.removeAll()
        for i in 0..<numberOfOTPdigit {
            let field = OTPTextField()
            field.keyboardType = .numberPad
            field.textColor = textFieldColor
            textFieldArray.append(field)
            addArrangedSubview(field)
            field.delegate = self
            field.backgroundColor = .clear
            field.textAlignment = .center
            field.addBottomBorderView(lineColor: bottomLineColor)
            i != 0 ? (field.previousTextField = textFieldArray[i-1]) : ()
            i != 0 ? (textFieldArray[i-1].nextTextFiled = textFieldArray[i]) : ()
            print("")
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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