从选择 UITextField 按下到另一个 UITextField 的转换是否会导致 UIView 在 Swift 中重新加载?

Can the transition from the selection UITextField press to another UITextField cause the UIView to reload in Swift?

我的应用加载后立即出现以下视图:

只要我点击全名文本字段,键盘就会显示并稍微移动元素以允许注册按钮保持显示。

当我移动到第二个文本字段时出现问题。它会导致视图完全重新加载并将视图中的所有元素放置到它们的原始位置,这使得键盘隐藏最低的元素。如下图所示

我已经搜索并检查了问题是否来自于键盘加载 keyboardwillshow()keyboardwillhide 当这个问题发生时根本没有被调用,正如我所验证的那样。

从选择 UITextField 按下到另一个 UITextField 的转换是否会导致 UIView 重新加载 Xcode?请注意,UIText 字段位于

import UIKit
import SendBirdSDK

class LoginController: UIViewController {

    var keyboardShowing = false

    let inputsContainerView: UIView = {
        let view = UIView()
        view.backgroundColor = UIColor.white
        view.translatesAutoresizingMaskIntoConstraints = false
        view.layer.cornerRadius = 5
        view.layer.masksToBounds = true

        return view
    }()

    lazy var loginRegisterButton: UIButton = {
        let button = UIButton(type: .system)
        button.backgroundColor = UIColor(r: 88, g: 101, b: 161)
        button.setTitle("Register", for: .normal)
        button.translatesAutoresizingMaskIntoConstraints = false
        button.setTitleColor(UIColor.white, for: .normal)
        button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 16)

        button.addTarget(self, action: #selector(handleLoginRegister), for: .touchUpInside)
        return button
    }()

    func handleLoginRegister() {
        if loginRegisterSegmentedControl.selectedSegmentIndex == 0 {
            handleLogin()
        } else {
            handleRegister()
        }
    }


    func handleLogin(){

        guard let userid = fullNameTextField.text, (passwordTextField.text != nil) else {
            print ("Form is not valid")
            return
        }



        SBDMain.connect(withUserId: userid, completionHandler: { (user, error) in
            if error != nil {
                print (error)
                return
            }

            //successfully loggedin user

            self.dismiss(animated: true, completion: nil)


        })
    }



    let nameTextField: UITextField = {
        let tf = UITextField()
        tf.placeholder = "Full Name"
        tf.translatesAutoresizingMaskIntoConstraints = false
        return tf
    }()

    let nameSeperatorView: UIView = {
        let view = UIView()
        view.backgroundColor = UIColor(r: 220, g: 220, b: 220)
        view.translatesAutoresizingMaskIntoConstraints = false
        return view

    }()

    let fullNameTextField: UITextField = {
        let tf = UITextField()
        tf.placeholder = "Username"
        tf.translatesAutoresizingMaskIntoConstraints = false
        return tf
    }()

    let fullNameSeperatorView: UIView = {
        let view = UIView()
        view.backgroundColor = UIColor(r: 220, g: 220, b: 220)
        view.translatesAutoresizingMaskIntoConstraints = false
        return view

    }()

    let passwordTextField: UITextField = {
        let tf = UITextField()
        tf.placeholder = "Password"
        tf.translatesAutoresizingMaskIntoConstraints = false
        tf.isSecureTextEntry = true
        return tf
    }()

    lazy var profileImageView: UIImageView = {
        let imageView = UIImageView()
        imageView.image = UIImage(named: "gameofthrones_splash")
        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageView.contentMode = .scaleAspectFill

        imageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleSelectProfileImageView)))
        imageView.isUserInteractionEnabled = true

        return imageView
    }()



    lazy var loginRegisterSegmentedControl: UISegmentedControl = {
        let sc = UISegmentedControl(items: ["Login", "Register"])
        sc.translatesAutoresizingMaskIntoConstraints = false
        sc.tintColor = UIColor.white
        sc.selectedSegmentIndex = 1
        sc.addTarget(self, action: #selector(handleLoginRegisterChange), for: .valueChanged)
        return sc
    }()

    func handleLoginRegisterChange() {
        if keyboardShowing == true {
            view.endEditing(true)
        }
        /*else  {
            view.endEditing(false)
        }*/

        let title = loginRegisterSegmentedControl.titleForSegment(at: loginRegisterSegmentedControl.selectedSegmentIndex)
        loginRegisterButton.setTitle(title, for: UIControlState())

        // change height of inputContainerView, but how???
        inputsContainerViewHeightAnchor?.constant = loginRegisterSegmentedControl.selectedSegmentIndex == 0 ? 100 : 150

        // change height of nameTextField
        nameTextFieldHeightAnchor?.isActive = false
        nameTextFieldHeightAnchor = nameTextField.heightAnchor.constraint(equalTo: inputsContainerView.heightAnchor, multiplier: loginRegisterSegmentedControl.selectedSegmentIndex == 0 ? 0 : 1/3)
        nameTextFieldHeightAnchor?.isActive = true
        nameTextField.isHidden = loginRegisterSegmentedControl.selectedSegmentIndex == 0

        fullNameTextFieldHeightAnchor?.isActive = false
        fullNameTextFieldHeightAnchor = fullNameTextField.heightAnchor.constraint(equalTo: inputsContainerView.heightAnchor, multiplier: loginRegisterSegmentedControl.selectedSegmentIndex == 0 ? 1/2 : 1/3)
        fullNameTextFieldHeightAnchor?.isActive = true

        passwordTextFieldHeightAnchor?.isActive = false
        passwordTextFieldHeightAnchor = passwordTextField.heightAnchor.constraint(equalTo: inputsContainerView.heightAnchor, multiplier: loginRegisterSegmentedControl.selectedSegmentIndex == 0 ? 1/2 : 1/3)
        passwordTextFieldHeightAnchor?.isActive = true

    }



    override func viewDidLoad() {
        super.viewDidLoad()



        view.backgroundColor = UIColor(r: 61, g: 91, b: 151)

        view.addSubview(inputsContainerView)
        view.addSubview(loginRegisterButton)
        view.addSubview(profileImageView)
        view.addSubview(loginRegisterSegmentedControl)


        setupInputsContainerView()
        setupLoginRegisterButton()
        setupProfileImageView()
        setupLoginRegisterSegmentedControl()

        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)

        //connecting to the application
        SBDMain.initWithApplicationId("1662A8E8-F45F-454B-9E5E-02362342ECC5")



    }

   func keyboardWillShow(notification: NSNotification) {

        print ("keyboardwillshow was called")

        if self.keyboardShowing {
            return
        }



            if self.keyboardShowing == false {
                self.inputsContainerView.frame.origin.y -= 58
                self.loginRegisterButton.frame.origin.y -= 58
                self.loginRegisterSegmentedControl.frame.origin.y -= 58
                self.profileImageView.frame.origin.y -= 58

            }
            self.keyboardShowing = true

    }

    func keyboardWillHide(notification: NSNotification) {

         print ("keyboardwillhide was called")

        if !self.keyboardShowing {
            return
        }


            if self.keyboardShowing == true {
                self.inputsContainerView.frame.origin.y += 58
                self.loginRegisterButton.frame.origin.y += 58
                self.loginRegisterSegmentedControl.frame.origin.y += 58
                self.profileImageView.frame.origin.y += 58
            }
            self.keyboardShowing = false

    }

    func setupLoginRegisterSegmentedControl() {
        //need x, y, width, height constraints
        loginRegisterSegmentedControl.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        loginRegisterSegmentedControl.bottomAnchor.constraint(equalTo: inputsContainerView.topAnchor, constant: -12).isActive = true
        loginRegisterSegmentedControl.widthAnchor.constraint(equalTo: inputsContainerView.widthAnchor, multiplier: 1).isActive = true
        loginRegisterSegmentedControl.heightAnchor.constraint(equalToConstant: 36).isActive = true
    }

    func setupProfileImageView(){

        //need x, y, width, height constraints
        profileImageView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        profileImageView.bottomAnchor.constraint(equalTo: loginRegisterSegmentedControl.topAnchor, constant: -12).isActive = true
        profileImageView.widthAnchor.constraint(equalToConstant: 150).isActive = true
        profileImageView.heightAnchor.constraint(equalToConstant: 150).isActive = true


    }

    var inputsContainerViewHeightAnchor: NSLayoutConstraint?
    var nameTextFieldHeightAnchor: NSLayoutConstraint?
    var fullNameTextFieldHeightAnchor: NSLayoutConstraint?
    var passwordTextFieldHeightAnchor: NSLayoutConstraint?

    func setupInputsContainerView(){
        //need x, y, width, height constraints
        inputsContainerView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        inputsContainerView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        print(self.inputsContainerView.frame.origin.y)
        inputsContainerView.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -24).isActive = true
        inputsContainerViewHeightAnchor = inputsContainerView.heightAnchor.constraint(equalToConstant: 150)
        inputsContainerViewHeightAnchor?.isActive = true

        inputsContainerView.addSubview(nameTextField)
        inputsContainerView.addSubview(nameSeperatorView)
        inputsContainerView.addSubview(fullNameTextField)
        inputsContainerView.addSubview(fullNameSeperatorView)
        inputsContainerView.addSubview(passwordTextField)

        //need x, y, width, height constraints
        nameTextField.leftAnchor.constraint(equalTo: inputsContainerView.leftAnchor, constant: 12).isActive = true
        nameTextField.topAnchor.constraint(equalTo: inputsContainerView.topAnchor).isActive = true

        nameTextField.widthAnchor.constraint(equalTo: inputsContainerView.widthAnchor).isActive = true
        nameTextFieldHeightAnchor = nameTextField.heightAnchor.constraint(equalTo: inputsContainerView.heightAnchor, multiplier: 1/3)
        nameTextFieldHeightAnchor?.isActive = true

        //need x, y, width, height constraints
        nameSeperatorView.leftAnchor.constraint(equalTo: inputsContainerView.leftAnchor).isActive = true
        nameSeperatorView.topAnchor.constraint(equalTo: nameTextField.bottomAnchor).isActive = true
        nameSeperatorView.widthAnchor.constraint(equalTo: inputsContainerView.widthAnchor).isActive = true
        nameSeperatorView.heightAnchor.constraint(equalToConstant: 1).isActive = true

        //need x, y, width, height constraints
        fullNameTextField.leftAnchor.constraint(equalTo: inputsContainerView.leftAnchor, constant: 12).isActive = true
        fullNameTextField.topAnchor.constraint(equalTo: nameTextField.bottomAnchor).isActive = true

        fullNameTextField.widthAnchor.constraint(equalTo: inputsContainerView.widthAnchor).isActive = true

        fullNameTextFieldHeightAnchor = fullNameTextField.heightAnchor.constraint(equalTo: inputsContainerView.heightAnchor, multiplier: 1/3)

        fullNameTextFieldHeightAnchor?.isActive = true

        //need x, y, width, height constraints
        fullNameSeperatorView.leftAnchor.constraint(equalTo: inputsContainerView.leftAnchor).isActive = true
        fullNameSeperatorView.topAnchor.constraint(equalTo: fullNameTextField.bottomAnchor).isActive = true
        fullNameSeperatorView.widthAnchor.constraint(equalTo: inputsContainerView.widthAnchor).isActive = true
        fullNameSeperatorView.heightAnchor.constraint(equalToConstant: 1).isActive = true

        //need x, y, width, height constraints
        passwordTextField.leftAnchor.constraint(equalTo: inputsContainerView.leftAnchor, constant: 12).isActive = true
        passwordTextField.topAnchor.constraint(equalTo: fullNameTextField.bottomAnchor).isActive = true

        passwordTextField.widthAnchor.constraint(equalTo: inputsContainerView.widthAnchor).isActive = true
        passwordTextFieldHeightAnchor = passwordTextField.heightAnchor.constraint(equalTo: inputsContainerView.heightAnchor, multiplier: 1/3)
        passwordTextFieldHeightAnchor?.isActive = true
    }

    func setupLoginRegisterButton(){

        //need x, y, width, height constraints
        loginRegisterButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        loginRegisterButton.topAnchor.constraint(equalTo: inputsContainerView.bottomAnchor, constant: 12).isActive = true
        loginRegisterButton.widthAnchor.constraint(equalTo: inputsContainerView.widthAnchor).isActive = true
        loginRegisterButton.heightAnchor.constraint(equalToConstant: 50).isActive = true

    }

    override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    }



}

extension UIColor {

    convenience init(r: CGFloat, g: CGFloat, b: CGFloat ) {
        self.init(red: r/255, green: g/255, blue: b/255, alpha: 1)
    }

}

不是移动 UIView 的元素,而是像这样移动整个视图框架:

func keyboardWillShow(notification: NSNotification) {

    print ("keyboardwillshow was called")

    if self.keyboardShowing {
        return
    }



        if self.keyboardShowing == false {
            /*self.inputsContainerView.frame.origin.y -= 58
            self.loginRegisterButton.frame.origin.y -= 58
            self.loginRegisterSegmentedControl.frame.origin.y -= 58
            self.profileImageView.frame.origin.y -= 58*/

            self.view.frame.origin.y -= 58

        }
        self.keyboardShowing = true

}

func keyboardWillHide(notification: NSNotification) {

     print ("keyboardwillhide was called")

    if !self.keyboardShowing {
        return
    }


        if self.keyboardShowing == true {
           /* self.inputsContainerView.frame.origin.y += 58
            self.loginRegisterButton.frame.origin.y += 58
            self.loginRegisterSegmentedControl.frame.origin.y += 58
            self.profileImageView.frame.origin.y += 58*/

            self.view.frame.origin.y += 58
        }
        self.keyboardShowing = false

}