Support for "snapping" to the bottom of a scroll view

`keyboardWillRecede` indicates that, if the user was to lift their finger at that moment, whether it would cause the keyboard to be dismissed. This is helpful when combined with `-[UIScrollView scrollViewWillEndDragging:withVelocity:targetContentOffset:targetContentOffset]`. Because this method usually gets called before the keyboard control's methods, we need to calculate it then. You can then do the following to snap the scrollView back to the bottom (iMessages does this).

    - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
    {
        if (self.view.keyboardWillRecede && velocity.y > -1.0 && velocity.y < 0.0) {
            targetContentOffset->y = scrollView.contentSize.height - scrollView.bounds.size.height;
        }
    }

For an even closer implementation, add an _startedAtBottom instance variable and use the following:

    - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
    {
        _startedAtBottom = scrollView.contentOffset.y == scrollView.contentSize.height - scrollView.bounds.size.height;
    }
    
    - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
    {
        if (_startedAtBottom && self.view.keyboardWillRecede && velocity.y > -1.0 && velocity.y < 0.0) {
            targetContentOffset->y = scrollView.contentSize.height - scrollView.bounds.size.height;
        }
    }

That will make is so that it only snaps to the bottom if it started out there when the user started to hide the keyboard.