tschoffelen
tschoffelen

Reputation: 520

How to make the tableHeaderView bounce along with UITableView

I have a UITableView with a tableHeaderView that is a large UIImageView. I want the UIImageView to stretch out when someone overscrolls to compensate for the space that would otherwise be empty.

I had that working before when using a simple UIScrollView, but it seems that I can't get it to work in a UITableViewCell, because setting the 'y' parameter of the UIImageView to a negative value seems to result in it being set to 0, as it doesn't want to overflow. The height does change though, so the delegate is setup correctly.

This is the code that is related to updating the frame in realtime:

func scrollViewDidScroll(scrollView: UIScrollView) {
    let pos = scrollView.contentOffset.y;
    if (pos <= 0){
        let height = self.view.frame.width - pos;
        self.picture!.frame = CGRectMake(0, pos, self.size().width, height);
    }
}

Should I change any settings on the UITableView to achieve the wanted effect?

EDIT
An example of what I wish to achieve:

Upvotes: 0

Views: 1033

Answers (1)

Rory McKinnel
Rory McKinnel

Reputation: 8014

I have given this a try and it is possible using the following approach:

1) Use a header view for the top cell. You provide this via the delegate viewForHeaderInSection.

2) Create this header view using a prototype cell to make life easy for yourself. Remember to return cell.contentView as the view.

3) Create a property for the header cell in your view controller.

self.headerCell;

4) In viewForHeaderInSection when you get section 0, if the self.headerCell property is nil, create the cell and configure. Otherwise return the existing self.headerCell.contentView

5) Define the prototype cell as follows:

a) Create a cell with a UIImageView and give the image view the following constraints:

i) Pin left and trailing edges to the contentView of the cell.

ii) Pin the top to the contentView top

iii) Give it a height constraint which is set to the height of the cell.

b) CTRL drag the top constraint and height constraint into the class for the header view cell and create IBOutlets. Lets call them constraintTop and constraintHeight.

6) VERY IMPORTANT. For the header cell contentView deselect clip subviews in the attribute inspector. Otherwise you can not see outside of the bounds of the cell.

7) In your table view controller add:

- (void) scrollViewDidScroll:(UIScrollView *)scrollView{
    NSLog(@"Scrolling pos = %f,%f",scrollView.contentOffset.x,scrollView.contentOffset.y);

    if (scrollView.contentOffset.y < 0){
        self.headerCell.constraintHeight.constant=self.headerCell.frame.size.height-scrollView.contentOffset.y;
        self.headerCell.constraintTop.constant=scrollView.contentOffset.y;
        [self.headerCell layoutIfNeeded];
    }
}

The result of this is that when you drag down, the constraints for the image height are increased and its position is moved up. Layout forces it to redisplay which causes it to fill in the gap. You can play around with this function to get the exact effect you want. Much depends on the display mode you set for the image.

I have tried this using a UIView with a background color and it works well.

You will need some tidy up when scrolling stops to set the constraints back to 0 and the height of the cell.

Upvotes: 1

Related Questions