Search code examples
swiftuibuttonuitextfielduitextfielddelegate

Reset characters left UILabel if the UITextField is being hidden


I have 5 UITextFields. 2 are visible and 3 could be extra "added" when a button is clicked (basically .isHidden = false but gives the illusion that its extra added). The 3 extra UITextFields also have a delete button (as a rightView) that when it's clicked, makes the .isHidden = true in an animation.

Now each UITextField has a UILabel (as rightView) that shows remaining characters. The problem is that when the user hits that delete button and the corresponding UITextField is hidden again, but the remaining characters UILabel keeps its old value. I'm not sure how to reset that. This is the code:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    guard let text = textField.text else { return true }
    let newLength = text.count + string.count - range.length

    var rightView = UIView()
    let label = UILabel(frame: CGRect(x: 0, y: 0, width: 20, height: 20))
    label.font = UIFont(name: Fonts.OpenSans_Light, size: 14)

    if textField === firstChoiceTextField || textField === secondChoiceTextField {
        rightView = UIView(frame: CGRect(x: 0, y: 0, width: 20, height: 25))
    }

    if textField === thirdChoiceTextField || textField === forthChoiceTextField || textField === fifthChoiceTextField {
        rightView = UIView(frame: CGRect(x: 0, y: 0, width: 55, height: 25))
        let button = UIButton(frame: CGRect(x: rightView.frame.width - 30, y: 0, width: 25, height: 25))
        button.setBackgroundImage(UIImage(named: "icon_cancel_dark"), for: .normal)
        button.addTarget(self, action: #selector(self.hideTextField(_:)), for: .touchUpInside)
        rightView.addSubview(button)
    }

    rightView.addSubview(label)
    textField.rightView = rightView
    textField.rightViewMode = .always
    label.textAlignment = .center

    // when the text field has been hidden with the hideTextField method below, the characters left label still shows the old count if the label is being shown again

    if newLength <= 35 {
        label.text =  String(50 - newLength)
        label.textColor = .lightGray
    }
    else {
        label.text =  String(50 - newLength)
        label.textColor = UIColor.red
    }

    return newLength < 50
}


@objc func hideTextField(_ sender: UIButton) {
    if let  field = sender.superview?.superview as? UITextField, !field.isHidden {
        UIView.animate(withDuration: 0.2) {
            field.text = ""
            field.isHidden = true
        }
    }
    if !self.thirdChoiceTextField.isHidden && !self.forthChoiceTextField.isHidden && !self.fifthChoiceTextField.isHidden {
        self.addTextFieldButton.isEnabled = false
    }
    else{
        self.addTextFieldButton.isEnabled = true
    }
}

Solution

  • In hideTextField(_ sender: UIButton) method, you can get the label from the rightView of the UITextfield that is going to hide as below

        if let  field = sender.superview?.superview as? UITextField, !field.isHidden {
    
            if let label = field.rightView?.subviews.filter({ $0 is UILabel }).first as? UILabel {
                print("I am the label. reset me")
                label.text = ""
            }
            UIView.animate(withDuration: 0.2) {
                field.text = ""
                field.isHidden = true
            }
        }