UIScrollView - set negative contentOffice when bounce animation starts

I use UITableView

to achieve a zoom / blur effect on my user profile picture (for example in Spotify app) when I pull UITableView

in negative contentOffset.y

. This all works great ...

Now when the user pulls down to contentOffset.y

less than or equal to a certain value -let calls it maintainOffsetY = 70.0

- and it "lets go" the view, I would like to maintain this contentOffset

until the user "pushes" the image up again, instead of automatically falling back to contentOffset = (0,0)


To achieve this, I have to know when touches started and ended, which I can do with the following delegate methods:

- (void) scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    // is like touches begin
    if ([scrollView isEqual:_tableView]) {
        NSLog(@"touches began");
        _touchesEnded = NO;
- (void) scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
// is like touches ended
NSLog(@"touches ended");
if ([scrollView isEqual:_tableView]) {
    _touchesEnded = YES;



Then in

- (void)scrollViewDidScroll:(UIScrollView *)scrollView


I check to see if it is less or less maintainOffsetY


, and if the user has already "released" the table, he is about to bounce (or already bounce) back to contentOffset = (0,0)


It seems impossible to bring it back just in maintainOffsetY

. Does anyone know a workaround or have an idea of ​​how to solve this?

Any help is greatly appreciated!


source to share

1 answer

To set negative offset in scroll view you can use this.

You need to keep the initial insertion of the scroll content. It may no longer be 0 if you have a semi-transparent navigation bar, for example.

    - (void)viewDidAppear:(BOOL)animated {
        [super viewDidAppear:animated];

        contentInsetTopInitial = self.tableView.contentInset.top;


Then write this.

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {

    CGPoint contentOffset = scrollView.contentOffset; // need to save contentOffset before changing contentInset
    CGFloat contentOffsetY = contentOffset.y + contentInsetTopInitial; // calculate pure offset, without inset

    if (contentOffsetY < -maintainOffsetY) {
        scrollView.contentInset = UIEdgeInsetsMake(contentInsetTopInitial + maintainOffsetY, 0, maintainOffsetY, 0);
        [scrollView setContentOffset:contentOffset animated:NO];


Hope this helps.



All Articles