UITextField частично скрыт клавиатурой при открытии - PullRequest
0 голосов
/ 24 сентября 2019

Я пытаюсь создать коллекцию из UITextField элементов.Я бы хотел, чтобы кнопка next на клавиатуре пропустила переход к следующему полю, и если это поле скрыто от просмотра клавиатурой, прокрутите его в поле зрения.

Это моя попытка.Он работает отдельно от 1 аспекта.

При закрытии клавиатуры и последующем выборе другого (или того же) поля ввод текста частично скрыт клавиатурой (см. Прикрепленный файл).

мясо и картофель находятся в пределах ViewController.

class ViewController: UIViewController {

    var activeField: UITextField?
    var lastOffset: CGPoint!
    var keyboardHeight: CGFloat!

    let scrollView: UIScrollView = {
        let scrollView = UIScrollView()
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        return scrollView
    }()

    let scrollViewContainer: UIStackView = {
        let view = UIStackView()
        view.axis = .vertical
        view.spacing = 10
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = .white

        view.addSubview(scrollView)
        scrollView.addSubview(scrollViewContainer)

        let totalFieldCount = 25

        for i in 1...totalFieldCount {
            let textField = createTextField(self, placeholder: "Field #\(i)", type: .default)

            textField.returnKeyType = i < totalFieldCount ? .next : .done
            textField.tag = i
            scrollViewContainer.addArrangedSubview(textField)
        }

        NSLayoutConstraint.activate([
            scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
            scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            scrollViewContainer.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
            scrollViewContainer.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor),
            scrollViewContainer.topAnchor.constraint(equalTo: scrollView.topAnchor),
            scrollViewContainer.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
            scrollViewContainer.widthAnchor.constraint(equalTo: scrollView.widthAnchor)
        ])

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

        scrollView.keyboardDismissMode = .interactive
    }

    func createTextField(_ delegate: UITextFieldDelegate?, placeholder: String, type: UIKeyboardType, isSecureEntry: Bool = false) -> UITextField {
        let tf = UITextField(frame: .zero)

        tf.placeholder = placeholder
        tf.backgroundColor = .init(white: 0, alpha: 0.03)
        tf.borderStyle = .roundedRect
        tf.font = .systemFont(ofSize: 14)
        tf.keyboardType = type
        tf.autocapitalizationType = .none
        tf.autocorrectionType = .no
        tf.isSecureTextEntry = isSecureEntry

        tf.heightAnchor.constraint(equalToConstant: 40).isActive = true

        if let delegate = delegate {
            tf.delegate = delegate
        }

        return tf
    }

}

extension ViewController: UITextFieldDelegate {

    func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
        activeField = textField
        lastOffset = self.scrollView.contentOffset
        return true
    }

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        let nextTag = textField.tag + 1

           if let nextResponder = textField.superview?.viewWithTag(nextTag) {
               nextResponder.becomeFirstResponder()
           } else {
            activeField?.resignFirstResponder()
            activeField = nil
        }

           return true
    }
}

extension ViewController {
    @objc func keyboardWillShow(notification: NSNotification) {

        guard keyboardHeight == nil else { return }

        if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
            keyboardHeight = keyboardSize.height

            UIView.animate(withDuration: 0.3, animations: {
                self.scrollView.contentInset.bottom = self.keyboardHeight
            })

            guard let activeField = activeField else { return }

            let distanceToBottom = self.scrollView.frame.size.height - (activeField.frame.origin.y) - (activeField.frame.size.height)
            let collapseSpace = keyboardHeight - distanceToBottom

            guard collapseSpace > 0 else { return }

            UIView.animate(withDuration: 0.3, animations: {
                self.scrollView.contentOffset = CGPoint(x: self.lastOffset.x, y: collapseSpace + 10)
            })
        }
    }

    @objc func keyboardWillHide(notification: NSNotification) {
        UIView.animate(withDuration: 0.3) {
            self.scrollView.contentOffset = self.lastOffset
            self.scrollView.contentInset.bottom = 0
        }

        keyboardHeight = nil
    }
}

enter image description here

1 Ответ

0 голосов
/ 24 сентября 2019

Заменить keyboardFrameBeginUserInfoKey на keyboardFrameEndUserInfoKey

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...