Search code examples
swiftuiviewuitextfieldviewdidappear

UITextField underline width issue


I have a UITextField & UIButton placed inside a vertical UIStackView. Programatically, I've added a UIView to serve as an underline of the UITextField.

The problem comes when I compile the code. The line is longer than the text field. I've printed the width of all of the objects above and it says 335.

I call this function in viewWillAppear and the line is longer. If I call it in viewDidAppear, the line is the exact width of the UITextField but you can see the button and text field flash very briefly before updating the view. What am I doing wrong? enter image description here enter image description here

override func viewDidLoad()  {
    super.viewDidLoad()
    observeKeyboardNotifications()
    textFieldDelegate()
    setupRegisterButton()

}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
     setupTextFields()
}

func setupTextFields() {

    emailTextField.leftViewMode = .always
    let emailIconView = UIImageView()
    emailIconView.frame = CGRect(x: 0, y: 0, width: 23, height: 17)
    emailIconView.image = UIImage(named: "icon_email")
    let bgIconView = UIView(frame: CGRect(x: 0, y: 0, width: 28, height: 17))
    bgIconView.addSubview(emailIconView)
    emailTextField.leftView = bgIconView

    emailTextField.tintColor = .white
    emailTextField.textColor = .white
    emailTextField.backgroundColor = .red
    emailTextField.borderStyle = .roundedRect
    let bottomLineEmail = CALayer()
    bottomLineEmail.frame = CGRect(x: 0, y: 29, width: emailTextField.frame.width, height: 1)
    print("Email width", emailTextField.frame.width)
    print("button width", retrievePasswordButton.frame.width)
    print("line width", bottomLineEmail.frame.width)
    bottomLineEmail.backgroundColor = UIColor.white.cgColor
    emailTextField.layer.addSublayer(bottomLineEmail)
    //emailTextField.backgroundColor = .clear
    emailTextField.attributedPlaceholder = NSAttributedString(string     : emailTextField.placeholder!,
                                                              attributes : [NSAttributedStringKey.foregroundColor: Colors.authTextFieldPlaceholderColor])
    retrievePasswordButton.isEnabled = false
    handleTextFields()
}

Solution

  • I checked it personally it works in ViewWillLayoutSubviews

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews();
        self.setupTextFields()
    }
    

    and viewDidAppear

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        self.setupTextFields();
    }
    

    proof