Как управлять высотой клавиатуры при использовании isSecureTextEntry в iOS UITextField - PullRequest
0 голосов
/ 09 апреля 2020

Существует вид с двумя UITextFields, и вид перемещается в соответствии с высотой клавиатуры. Однако перемещение представления не является идеальным, если хотя бы для одного текстового поля свойство isSecureTextEntry имеет значение true. Это заметно при перемещении между текстовыми полями. Вид перемещается вниз один раз и мгновенно возвращается. Это потому, что высота клавиатуры меняется на мгновение. Я думаю, что это вопрос показа / скрытия QuickTypeBar. Итак, как устранить этот эффект и контролировать движение вида?

Ниже приведен весь код. Это может не выглядеть прямо в симуляторе. Потому что панель QuickType не отображается. Это происходит на iPhone X iOS13.3.1.

Спасибо.

enter image description here enter image description here

import UIKit

class ViewController: UIViewController {

    public var boardView: UIView!
    public var usernameTextField: UITextField!
    public var passwordTextField: UITextField!

    public var boardViewBottomAnchorConstraint: NSLayoutConstraint!
    public var boardViewBottomAnchorConstraintConstant: CGFloat = -220
    public var offset: CGFloat = 16.0

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .darkGray

        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChangeFrame(_:)), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)

        var constraints = [NSLayoutConstraint]()

        let boardView = UIView()
        boardView.backgroundColor = .brown
        boardView.layer.cornerRadius = 16.0
        boardView.translatesAutoresizingMaskIntoConstraints = false
        boardViewBottomAnchorConstraint = boardView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: boardViewBottomAnchorConstraintConstant)
        constraints.append(boardView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 16))
        constraints.append(boardViewBottomAnchorConstraint)
        constraints.append(boardView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -16))
        view.addSubview(boardView)
        self.boardView = boardView

        let usernameTextField = UITextField()
        usernameTextField.backgroundColor = .white
        usernameTextField.delegate = self
        usernameTextField.returnKeyType = .next
        usernameTextField.textContentType = .username
        usernameTextField.placeholder = "USERNAME TEXTFIELD"
        usernameTextField.translatesAutoresizingMaskIntoConstraints = false
        constraints.append(usernameTextField.heightAnchor.constraint(equalToConstant: 56))
        constraints.append(usernameTextField.topAnchor.constraint(equalTo: boardView.topAnchor, constant: 100))
        constraints.append(usernameTextField.leftAnchor.constraint(equalTo: boardView.leftAnchor, constant: 24))
        constraints.append(usernameTextField.rightAnchor.constraint(equalTo: boardView.rightAnchor, constant: -24))
        boardView.addSubview(usernameTextField)
        self.usernameTextField = usernameTextField

        let passwordTextField = UITextField()
        passwordTextField.backgroundColor = .white
        passwordTextField.delegate = self
        passwordTextField.returnKeyType = .go
        passwordTextField.textContentType = .password
        passwordTextField.placeholder = "PASSWORD TEXTFIELD"
        passwordTextField.translatesAutoresizingMaskIntoConstraints = false
        constraints.append(passwordTextField.heightAnchor.constraint(equalToConstant: 56))
        constraints.append(passwordTextField.topAnchor.constraint(equalTo: usernameTextField.bottomAnchor, constant: 50))
        constraints.append(passwordTextField.leftAnchor.constraint(equalTo: boardView.leftAnchor, constant: 24))
        constraints.append(passwordTextField.bottomAnchor.constraint(equalTo: boardView.bottomAnchor, constant: -100))
        constraints.append(passwordTextField.rightAnchor.constraint(equalTo: boardView.rightAnchor, constant: -24))
        boardView.addSubview(passwordTextField)
        self.passwordTextField = passwordTextField

        NSLayoutConstraint.activate(constraints)

        let tap = UITapGestureRecognizer(target: view, action: #selector(UIView.endEditing(_:)))
        view.addGestureRecognizer(tap)

        // false is the ideal move. If true, the view moves violently.
        passwordTextField.isSecureTextEntry = true

    }

}

extension ViewController {

    @objc
    public func keyboardWillShow(_ notification: Notification) { print("WILL SHOW")
        updateConstraints(notification)
    }

    @objc
    public func keyboardWillHide(_ notification: Notification) { print("WILL HIDE")
        boardViewBottomAnchorConstraint.constant = boardViewBottomAnchorConstraintConstant
        view.layoutIfNeeded()
    }

    @objc
    public func keyboardWillChangeFrame(_ notification: Notification) { print("WILL CHANGE FRAME")
        updateConstraints(notification)
    }

    private func updateConstraints(_ notification: Notification) {
        guard
            let toFrame = notification.userInfo?[UIApplication.keyboardFrameEndUserInfoKey] as? CGRect,
            let fromFrame = notification.userInfo?[UIApplication.keyboardFrameBeginUserInfoKey] as? CGRect else { return }
        print(fromFrame); print(toFrame);
        let constant = -toFrame.size.height - offset
        boardViewBottomAnchorConstraint.constant = constant
        view.layoutIfNeeded()
    }

}

extension ViewController: UITextFieldDelegate {

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        if textField == usernameTextField {
            passwordTextField.becomeFirstResponder()
        } else {
            passwordTextField.resignFirstResponder()
        }
        return true
    }

}

Ответы [ 2 ]

1 голос
/ 09 апреля 2020

попробуйте использовать github.com / hackiftekhar / IQKeyboardManager из кокапод. внутри документации вы должны добавить несколько строк в класс appdelegate, и вы хороши для go. IQKeyboardmanager доступен как через cocoapods, так и через IOS менеджер быстрой зависимости.

0 голосов
/ 09 апреля 2020
if UIApplication.shared.isKeyboardPresented {
     print("Keyboard presented")
} else { 
     print("Keyboard is not presented")
}

Используйте этот код в сочетании с вашим кодом. Определите, когда клавиатура активна, и выполните ваши действия соответственно

edit ----

Вам нужно Ctrl + перетащить из каждого из ваших текстовых полей в ваш код и создать @IBAction

@IBAction func textField1() {
    //when a user taps on text field 1. this code block is triggered. 
    if UIApplication.shared.isKeyboardPresented {
        print("Keyboard presented")
        //if the keyboard is already presented do whatever other action is required 
        //inside here the keyboard is already active
    } else { 
        print("Keyboard is not presented")
        //if the keyboard is not currently active do any required action here
        //Inside here the keyboards will become active 
    }
}

Для всех остальных текстовых полей и всех других представлений вам нужно сделать то же самое и настроить свой код на основе действий

EDI ----

Ниже приведено как вы можете достичь той же функциональности без использования конструктора интерфейса

let textField = UITextField()
self.textField.addTarget(self, action: #selector(targetFunc), for: .touchUpInside)

@objc func targetFunc() {
    // same actions as above in here
}
...