Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoiding Keyboard #52

Closed
schmidan opened this issue Apr 18, 2019 · 2 comments

Comments

Projects
None yet
2 participants
@schmidan
Copy link

commented Apr 18, 2019

enjoying this small but very handy framework a lot. thanks for the effort and making it os.

i wonder if there is a simple built in way to avoid the keyboard or do we have to handle the content insets our own via keyboardWillShowNotification?

adding stackView.addRow(UITextField()) as the last element of your demo shows this issue nicely:
the TextField gets obscured by the keyboard as soon as it becomes the first responder.

  private func setUpRows() {
    setUpDescriptionRow()
    setUpSwitchRow()
    setUpHiddenRows()
    setUpExpandingRowView()
    setUpPhotoRow()

    stackView.addRow(UITextField())
  }
@tadija

This comment has been minimized.

Copy link
Contributor

commented May 3, 2019

Hi @schmidan, I wrote this small wrapper which works well for me:

import AloeStackView

/// This class adds automatic scroll functionality when keyboard will show or hide.
open class AutoScrollStackViewController: AloeStackViewController {

    // MARK: Properties

    open var defaultContentInset: UIEdgeInsets = .zero {
        didSet {
            updateContentInset(with: defaultContentInset)
        }
    }

    open var keyboardTopMargin: CGFloat = 20

    // MARK: Lifecycle

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

        addObservers()
    }

    open override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)

        NotificationCenter.default.removeObserver(self)
    }

    // MARK: Keyboard Observers

    @objc
    open func keyboardWillShow(_ notification: Notification) {
        let keyboardFrameValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue
        guard var keyboardFrame = keyboardFrameValue?.cgRectValue else { return }
        keyboardFrame = stackView.convert(keyboardFrame, from: nil)
        let keyboardSize = keyboardFrame.size

        let bottomInset = keyboardSize.height + keyboardTopMargin
        let keyboardInset = UIEdgeInsets(
            top: defaultContentInset.top,
            left: defaultContentInset.left,
            bottom: bottomInset,
            right: defaultContentInset.right
        )

        updateContentInset(with: keyboardInset)
    }

    @objc
    open func keyboardWillHide(_ notification: Notification) {
        updateContentInset(with: defaultContentInset)
    }

    // MARK: Helpers

    private func updateContentInset(with inset: UIEdgeInsets) {
        stackView.contentInset = inset
        stackView.scrollIndicatorInsets = inset
    }

    private func addObservers() {
        let nc = NotificationCenter.default
        nc.addObserver(
            self, selector: #selector(keyboardWillShow(_:)),
            name: UIResponder.keyboardWillShowNotification, object: nil
        )
        nc.addObserver(
            self, selector: #selector(keyboardWillHide(_:)),
            name: UIResponder.keyboardWillHideNotification, object: nil
        )
    }

}

Still not sure if something like this should be integrated into AloeStackViewController though (since keyboard is not always needed), but it might be...

@schmidan

This comment has been minimized.

Copy link
Author

commented Jun 4, 2019

Thanks a bunch for the wrapper class. I have a similar solution but using composition.

i believe you are right and this should not be the responsibility of the stack view. as such, this issue can be closed

@schmidan schmidan closed this Jun 4, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.