Jacob Parker
Jacob Parker

Reputation: 307

iOS Interactive Keyboard Reveal

On Facebook Messenger for iOS, it has it so if the keyboard is hidden, if you swipe up, the keyboard will show. It does this exactly in reverse to the interactive keyboard dismissal mode: the keyboard reveals itself as you swipe up at the speed in which you swipe up.

Does anybody have any pointers on how to do this?

Edit: thanks for the answers! I was mostly looking into whether there was a built-in way to do this, since I saw it being done in Facebook Messenger. However, I just read a blog post where they said they had to screenshot the system keyboard to get the effect—so I’ll assume there’s no built-in way to do this! As mentioned in the comments, I’m using a custom keyboard, so this should be a lot easier, since I have control over the frame!

Upvotes: 2

Views: 698

Answers (2)

Woody Jean-louis
Woody Jean-louis

Reputation: 535

Here is an implementation that worked for me. It's not perfect but it works fairly well and is simple to implement.You will need a collection view or a table view.

For the sake of simplicity I will only show code that is necessary for this feature. so please handle everything else that is necessary for the views' initialization.

class ViewController: UIViewController {
    var collectionView: UICollectionView!
    var textView: UITextView!

    override func viewDidLoad() {
        super.viewDidLoad()

        collectionView.panGestureRecognizer.addTarget(self, action: #selector(handlePan(_:)))
        collectionView.keyboardDismissMode = .interactive
        // Only necessary for empty collectionView
        collectionView.alwaysBounceVertical = true
    }

    func handlePan(_ sender: UIPanGestureRecognizer) {
        if sender.state == .changed {
            let translation = sender.translation(in: view)

            if translation.y < 0 && collectionView.isAtBottom && !self.textView.isFirstResponder() {
                self.textView.becomeFirstResponder()
            }
        }
    }
}

extension UIScrollView {

    var isAtBottom: Bool {
        return contentOffset.y >= verticalOffsetForBottom
    }

    var verticalOffsetForBottom: CGFloat {
        let scrollViewHeight = bounds.height
        let scrollContentSizeHeight = contentSize.height
        let bottomInset = contentInset.bottom
        let scrollViewBottomOffset = scrollContentSizeHeight + bottomInset - scrollViewHeight
        return scrollViewBottomOffset
    }

}

Upvotes: 1

Oleh Zayats
Oleh Zayats

Reputation: 2443

Basically you'll need UIPanGestureRecognizer.

  1. Set UIScreenEdgePanGestureRecognizer for bottom edge, UIPanGestureRecognizer for hiding the keyboard in Storyboard and drag @IBAction outlets to the code.

  2. Set you keyboard view container with your keyboard in the bottom of the controller in Storyboard, so that user doesn't see it. Drag an @IBOutlet to your code so that you'll be able to modify it's frame.

  3. In gesture actions when dragging your animate the view movement.

  4. When stopped dragging you need to check the view's position and animate it to the destination if it's not there yet.

  5. Also you'll need to add a check for the dragging area so that user cannot drag it further.

It's simple, you'll just need to check all cases and test it properly.

This is a basic setup you can build from this:

class ViewController: UIViewController {

    @IBOutlet weak var keyboardContainerView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func onEdgePanGestureDrag(_ sender: UIScreenEdgePanGestureRecognizer) {
        let point = sender.location(in: view)

        view.layoutIfNeeded()
        UIView.animate(withDuration: 0.33) {
            // Animate your custom keyboard view's position
            self.keyboardContainerView.frame = CGRect(x: self.keyboardContainerView.bounds.origin.x,
                                                      y: point.y,
                                                      width: self.keyboardContainerView.bounds.width,
                                                      height: self.keyboardContainerView.bounds.height)
        }
        view.layoutIfNeeded()
    }

    @IBAction func onPanGestureDrag(_ sender: UIPanGestureRecognizer) {
        let point = sender.location(in: view)

        view.layoutIfNeeded()
        UIView.animate(withDuration: 0.33) {
            // Animate your custom keyboard view's position
            self.keyboardContainerView.frame = CGRect(x: self.keyboardContainerView.bounds.origin.x,
                                                      y: point.y,
                                                      width: self.keyboardContainerView.bounds.width,
                                                      height: self.keyboardContainerView.bounds.height)
        }
        view.layoutIfNeeded()
    }
}

Upvotes: 4

Related Questions