Table Views on top of Map Views

123

Code for this tutorial is available on GitHub.

One of the features of Turkish Things is that its UIMapView plays nice with its accompanying UITableView. When you scroll the UITableView upwards, it will cover the UIMapView to give you the most screen real estate that you can have. If you scroll it down, you will see that the UIMapView will resize itself to cover the entire screen. I always wanted it to behave this way, and I was having trouble implementing it. Then my Flatiron School instructor Joe showed me how to do it. All it took was to subclass UITableView and override a few methods.

This is the idea: On our storyboard, we’ll put a UIMapView and cover it with a UITableView. Then we’ll create an edge inset on our UITableView so the cells will start after a certain space from the top. We’ll then make the background color of the UITableView transparent so that the underlying UIMapView is visible. We’ll also need to handle the taps; we’ll need to transfer the user taps and gestures that are made on the UITableView to the UIMapView.

Here is how it’s done:

1) Subclass UITableView, and override hitTest method: The only reason we’re doing this is to handle the user taps and gestures so that the user can interact with the underlying UIMapView:

On your MYTableView.m:

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    id hitView = [super hitTest:point withEvent:event];
    if (point.y<0) {
        return nil;
    }
    return hitView;
}

2) Create a UIEdgeInset so that the UITableViewCells start after a certain space:Because the UIMapView is covered with the UITableView, we need to create a space so that the UIMapView will be visible:

On your ViewController.m:

-(void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    self.tableView.contentInset = UIEdgeInsetsMake(self.mapView.frame.size.height-40, 0, 0, 0);
}

3) Override scrollViewDidScroll to prevent the UITableView from scrolling down too much: We want the user to be able to pull the UITableView down no more than the height of the UIMapView (otherwise you see the white space where the UIMapView ends)

On your ViewController.m

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
    if (scrollView.contentOffset.y < self.mapView.frame.size.height*-1 ) {
        [scrollView setContentOffset:CGPointMake(scrollView.contentOffset.x, self.mapView.frame.size.height*-1)];
    }
}

4) Finally, make the UITableView background transparent: If you don’t do this, then the UITableView is not visible (it’s covered with the default white background color of the UITableView).

On your ViewController.m

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.tableView.backgroundColor = [UIColor clearColor];
    self.tableView.delegate = self;
    self.tableView.dataSource = self;
}

Code for this tutorial is available on GitHub.

This entry was posted in Uncategorized. Bookmark the permalink.

2 Responses to Table Views on top of Map Views

  1. Loadex says:

    Hi, thanks for the tutorial !
    I tried it and it worked perfectly, however, i tried to add a search bar in my tableview and the
    self.tableView.contentInset = UIEdgeInsetsMake(self.mapView.frame.size.height-40, 0, 0, 0);
    is not applyed when the view appear, any idea why it is happening ?

    • Loadex says:

      Found my mistake, maybe you should update your tutorial, you also have to set :
      scrollView.contentOffset = CGPointMake(0.0f, -40.0f); with the contentInset ! 🙂

Leave a comment