Using the background of a UITableView as a scroll indicator

There is a fancy solution to present the scrolling position of a tableview to the user using moving image as a background. The user can better imagine the size of the table view because the background image suggest where he/she is in the tableview.

How-To – short version

  1. Add a tableview
  2. create a scrollview with an imageview which size and contentSize is the same as the tableview
  3. add the scrollview as a background view of the tableview
  4. set the tableview to transparent
  5. Good To Know: the TableView is a ScrollView so you can handle all ScrollViewDelegate related methods. Just simply implement the ScrollView delegate methods where you implemented the TableViewDelegate methods: catch the tableview’s scrolling event and position the scroll position of the background scrollview accordingly

How-To – detailed version

The sample source uses ARC.

First, in the ViewDidLoad of your ViewController load the appropriate image, create an image view which presents it  and add the ImageView as the subview of your ScrollView:

- (UIView *)createBackgroundScrollViewWithFrame:(CGRect)tableViewFrame {

    // set up the image view, select a long image
    UIImage *img = [UIImage imageNamed:kImageName];

    // create image view with the image, the size should be long enough for the scroll
    UIImageView *imgView = [[UIImageView alloc] initWithImage:img];
    imgView.contentMode = UIViewContentModeScaleToFill;
    imgView.frame = CGRectMake(0,0, tableViewFrame.size.width, img.size.height);

    // set up the background scroll view and add the image view
    UIScrollView *backgroundScrollView = [[UIScrollView alloc] initWithFrame:tableViewFrame];
    backgroundScrollView.userInteractionEnabled = NO;
    backgroundScrollView.contentSize = imgView.frame.size;
    [backgroundScrollView addSubview:imgView];

    return backgroundScrollView;
}

 

Second, set the ScrollView as the backgroundView of your tableView:

    // set the scroll view as the background view of the tableview
    myTableView.backgroundView = [self createBackgroundScrollViewWithFrame:theTableView.bounds];

Third, don’t forget to set the background color of the cells to clearColor if you use the tableView in grouped mode:

cell.backgroundColor = [UIColor clearColor];

Fourth implement the appropriate ScrollViewDelegate method of the TableView (scrollViewDidScroll). Notice that I modified the parameter to UITableView instead of UIScrollView. This is not necessary but makes to code more clear and you don’t have to cast a lot. We should calculate the correct position by the proportion of the contentSize of the TableView and the ScrollView.

// cheat a bit: modify the parameter to UITableView from UIScrollView
- (void)scrollViewDidScroll:(UITableView *)aTableview {

    if (aTableview != myTableView) {
        return;
    }
    UIScrollView *backgroundScrollView = (UIScrollView*)aTableview.backgroundView;

    // calculate the position of the scroll regarding to the position of the tableview
    float diffTableView = aTableview.contentSize.height - aTableview.frame.size.height;
    if (diffTableView>0) {
        float diffScroll = backgroundScrollView.contentSize.height - backgroundScrollView.frame.size.height;
        float newOffset = aTableview.contentOffset.y * (diffScroll/diffTableView);

        backgroundScrollView.contentOffset = CGPointMake(backgroundScrollView.contentOffset.x, newOffset);
    }
}

 

Notes: The image should be long enough to see the correct effect.

If you put a frame around your content you should play with margins and spacings:  you have to set up a header and footer and indent of each cell.

If you use sections take care of indenting the sections as well. You can achieve by implementing the  tableView:viewForHeaderInSection and return a UIView which contains a UILabel indenting appropriately.

You can set a semitransparent background color for each cell and/or you can use a faded image.

Download the sample project:

TableViewAutoScrollingBackground.zip