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

时间:2017-08-10 12:44:03

标签: swift uiview uitextfield uikeyboard

我的应用加载后,我有以下视图:

Figure 1: First view load

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

Figure 2: App view after I click on the first UITextfield

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

Figure 3 showing the problem

我已经搜索并检查问题是否来自于键盘加载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)
    }

}

1 个答案:

答案 0 :(得分:0)

而不是移动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

}