Rectangle 27 0

objective c iOS: Stretching Resizing UITableView Header As The User Drags Down?


-(void)someInitMethod {
   initialFrame = yourHeaderView.frame;
}
-(void)scrollViewDidScroll:(UIScrollView*)scrollView {
    if(scrollView.contentOffset.y < 0) {
       initialFrame.size.height -= scrollView.contentOffset.y;
       yourHeaderView.frame = initialFrame;
    }
}

Also make sure you set the proper contentMode for your UIImageView. Also I think this implementation will create a bouncing effect but I'm not sure because I can't test it right now but I think this is a good start point for you.

First of all you should remove the UIImageView from the header and add it as a simple UIImageView on top of the UITableView then since UITableViewDelegate protocol conforms to UIScrollViewDelegate protocol you can implement the scrollViewDidScroll: method to check when the tableView is scrolling down and has a bouncing effect. something like this:

Hey Dany thanks for your time! I have followed your advice and have tried what you recommended. For some reason though, as I drag down, the image just disappears, and never returns. The bouncing effect is implemented which I like though. Any suggestions? I have updated my question to show you what I tried.

Please check the ` initialFrame.size.height -= scrollView.contentOffset.y;` I think there is a + instad of - but I'm not sure. So first check the image view frame in scrollViewDidScroll and after that if everything is correct check if there is a need for setNeedsDisplay on imageView to redraw the image.

The math is incorrect, this would make it look jerky as it keeps adding up to bigger and bigger number instead of increments of the difference.

Note
Rectangle 27 0

objective c iOS: Stretching Resizing UITableView Header As The User Drags Down?


I recently posted a blog post about accomplishing this using constraints which might help, turns out it was quite straight forward.

Note
Rectangle 27 0

objective c iOS: Stretching Resizing UITableView Header As The User Drags Down?


-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
float scrollViewHeight = scrollView.frame.size.height;
float scrollContentSizeHeight = scrollView.contentSize.height;
float scrollOffset = scrollView.contentOffset.y;

if (scrollOffset == 0)
{
    // then we are at the top
}
else if (scrollOffset + scrollViewHeight == scrollContentSizeHeight)
{
    // then we are at the end
   // Do what you need here 
}

I dont know if this would help you or not ..

Note
Rectangle 27 0

objective c iOS: Stretching Resizing UITableView Header As The User Drags Down?


contentInset
  • Add a Map View (or whatever view) below the Table View so that it will get rendered over the top. It will look like it is overlapping.
  • Add a Table View and set the constraints to 0 from all sides.
  • Add constraints to the top left and right.
  • Create a View Controller in storyboard.
  • In the view controller add the following code, which resizes the view based on the scrolling: func scrollViewDidScroll(scrollView: UIScrollView) { var scrollOffset = scrollView.contentOffset.y var headerFrame = mapView.frame if (scrollOffset < 0) { // Adjust map headerFrame = CGRect(x: mapView.frame.origin.x, y: mapView.frame.origin.y, width: mapView.frame.size.width, height: -scrollOffset) } else { // Adjust map headerFrame = CGRect(x: mapView.frame.origin.x, y: mapView.frame.origin.y, width: mapView.frame.size.width, height: 0) } mapView.frame = headerFrame }
  • In the view controller viewDidLoad add the following: tableView.contentInset = UIEdgeInsetsMake(200, 0, 0, 0) where 200 is the height of the View. This will push the contents of the table view downwards.

This is how I achieved it, in my case I was using a map view up the top:

Note
Rectangle 27 0

objective c iOS: Stretching Resizing UITableView Header As The User Drags Down?


-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    float scrollViewHeight = scrollView.frame.size.height;
    float scrollContentSizeHeight = scrollView.contentSize.height;
    float scrollOffset = scrollView.contentOffset.y;

    if (scrollOffset == 0)
    {
        // then we are at the top
    }
    else if (scrollOffset + scrollViewHeight == scrollContentSizeHeight)
    {
        // then we are at the end
        // Do what you need here 
    }
}

I don't know, if this would help you or not ..

Note
Rectangle 27 0

objective c iOS: Stretching Resizing UITableView Header As The User Drags Down?


Please have a look at this https://github.com/matteogobbi/MGSpotyViewController which implements the same effect as per your requirement.

Note
Rectangle 27 0

objective c iOS: Stretching Resizing UITableView Header As The User Drags Down?


- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
      if (scrollView.contentOffset.y < initialScrollOffset) {
           CGRect frame = self.headerView.frame;
           frame.size.height = self.tableView.tableHeaderView.frame.size.height - scrollView.contentOffset.y;
           frame.origin.y = self.tableView.tableHeaderView.frame.origin.y + scrollView.contentOffset.y;
           self.headerView.frame = frame;
    }
}
- (void)viewDidLoad
{
    [super viewDidLoad];

    // Remove view from table header and place it in the background instead.
    [self.headerView removeFromSuperview];
    UIView *backgroundView = [UIView new];
    [backgroundView addSubview:self.headerView];
    self.tableView.backgroundView = backgroundView;
}

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

    /* Set initialScrollOffset ivar to start offset, because in my case
       the scroll offset was affected by the statusbar + navigation bar heights
       and the view controller's "extend edges under top bars" option. */
    initialScrollOffset = self.tableView.contentOffset.y;
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    /* Modify headerView height only if the table content gets pulled
       beyond initial offset. */
    if (scrollView.contentOffset.y < initialScrollOffset) {
        CGRect frame = self.headerView.frame;
        frame.size.height = self.tableView.tableHeaderView.frame.size.height + -scrollView.contentOffset.y;
        self.headerView.frame = frame;
    }
}
scrollViewDidScroll:
  • Build up your table header in interface builder as described above: 1 UIView as container with a 2nd UIView embedded within.
  • Create a UITableView within a UIViewController (or try it with a UITableViewController).
  • Drop a 2nd UIView within the table header UIView and make it the same size as it's parent. This will be the actual header, so feel free to give it any color, setup an image view or other content.
  • Drop a UIView at the top (but within) the UITableView, so it becomes a table header above the first cell.
  • Give this header view a desired height (like 200px for example) and set the background color to "Clear Color". The Clear Color is important, the view needs to be see-through.
  • Skip the viewDidLoad code above, there is no need to pull the UIView out of it's container and we won't need to set it as a table background.

Also, steps 1 to 5 are completely optional of course. You can programmatically create your header view or use a XIB instead. As long as you make sure the table has a Clear Colored header view set with the same height as your desired header because this serves as a spacer to keep your cells and section titles in line.

I needed this implementation only for a stretching header with background color and labels. It should be easy to add a UIImageView to this header though.

That's it. Only visual difference from the other solution is that the contents will now scroll up along with the rest of the cells instead of being overlapped by them.

The earlier solutions on this page gave me some trouble when I needed this to work along with section titles and index bar, so I came up with the following alternative myself. Please note; I don't use autolayout in my project and I've only tested this on iOS9+;

Note
Rectangle 27 0

objective c iOS: Stretching Resizing UITableView Header As The User Drags Down?


-(void)someInitMethod {
   initialFrame = yourHeaderView.frame;
}
-(void)scrollViewDidScroll:(UIScrollView*)scrollView {
    if(scrollView.contentOffset.y < 0) {
       initialFrame.size.height -= scrollView.contentOffset.y;
       yourHeaderView.frame = initialFrame;
    }
}

Also make sure you set the proper contentMode for your UIImageView. Also I think this implementation will create a bouncing effect but I'm not sure because I can't test it right now but I think this is a good start point for you.

First of all you should remove the UIImageView from the header and add it as a simple UIImageView on top of the UITableView then since UITableViewDelegate protocol conforms to UIScrollViewDelegate protocol you can implement the scrollViewDidScroll: method to check when the tableView is scrolling down and has a bouncing effect. something like this:

Hey Dany thanks for your time! I have followed your advice and have tried what you recommended. For some reason though, as I drag down, the image just disappears, and never returns. The bouncing effect is implemented which I like though. Any suggestions? I have updated my question to show you what I tried.

Please check the ` initialFrame.size.height -= scrollView.contentOffset.y;` I think there is a + instad of - but I'm not sure. So first check the image view frame in scrollViewDidScroll and after that if everything is correct check if there is a need for setNeedsDisplay on imageView to redraw the image.

The math is incorrect, this would make it look jerky as it keeps adding up to bigger and bigger number instead of increments of the difference.

Note
Rectangle 27 0

objective c iOS: Stretching Resizing UITableView Header As The User Drags Down?


@CyberDandy You are correct, the table view header view does behave differently

I recently posted a blog post about accomplishing this using constraints which might help, turns out it was quite straight forward.

That is indeed great, but it is of no use for @KingPolycon, as he is using an image at the top of a table view, and in this case it is a lot more tricky to handle - I'm still looking into it myself. Though I guess he either found a way to do it or changed drastically his approach since he posted this question :p.

This is the reason one should answers along with links. The link is dead. I'm going to downvote this. It's a 7 upvotes that is worth nothing now. I'll Upvote again when the link is back up or some sort of answer is added.

You're right about posting with links, however if you really need it, here you go: web.archive.org/web/20160326225445/http://

Note